Ошибка С# в операторе по модулю %

Решив одну ошибку, я пришел к интересным открытиям.

Результат этой процедуры

    static void Main(string[] args)
    {
        int i4 = 4;
        Console.WriteLine("int i4 = 4;");
        Console.WriteLine("i4 % 1 = {0}", i4 % 1);

        double d4 = 4.0;
        Console.WriteLine("double d4 = 4.0;");
        Console.WriteLine("d4 % 1 = {0}", d4 % 1);
        Console.WriteLine("-----------------------------------------------------------");
        int i64 = 64;
        double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0);
        Console.WriteLine("int i64 = 64;");
        Console.WriteLine("double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0) = {0}", dCubeRootOf64);
        Console.WriteLine("dCubeRootOf64 = {0}", dCubeRootOf64);
        Console.WriteLine("dCubeRootOf64 % 1 = {0} ??????????????  Why 1. ??????????", dCubeRootOf64 % 1);

        Console.ReadLine();
    }

is

int i4 = 4;
i4 % 1 = 0
double d4 = 4.0;
d4 % 1 = 0
-----------------------------------------------------------
int i64 = 64;
double dCubeRootOf64 = Math.Pow(i64, 1.0 / 3.0) = 4
dCubeRootOf64 = 4
dCubeRootOf64 % 1 = 1 ??????????????  Why 1. ??????????

int 4 % 1 = 0 -- верно

double 4.0 % 1 = 0 -- верно

Но ошибка в:

Math.Pow(64, 1,0 / 3,0) % 1 = 1

Кубический корень из 64 равен 4. Почему в таком случае 4 % 1 = 1?


person SelvirK    schedule 24.05.2012    source источник
comment
Проверьте Google: (64^(1/3)) мод 1   -  person SQLMason    schedule 24.05.2012
comment
Если вы хотите убедиться, что это целое число, для которого вы получаете модуль, попробуйте привести его.   -  person SQLMason    schedule 24.05.2012
comment
Вы ищете это, я думаю, разница между десятичным числом с плавающей запятой и двойным значением в c">stackoverflow.com/questions/618535/   -  person Nevyn    schedule 24.05.2012
comment
возможный дубликат Почему оператор модуля не работает для двойного в С#?   -  person Ian Mercer    schedule 24.05.2012
comment
@IanMercer: Нет, это не дубликат   -  person SLaks    schedule 24.05.2012
comment
Math.Pow(x, 1.0 / 3.0) не вычисляет кубический корень, даже если Pow был бесконечно точным (а это не так), потому что 1.0 / 3.0 не одна треть, а 0,333333333333333331.   -  person harold    schedule 24.05.2012


Ответы (2)


Math.Pow(64, 1.0 / 3.0) возвращает 3.9999999999999996.
При отображении округляется до 4.

Взяв его по модулю 1, вы получите 0.99999999999999956, который аналогичным образом округляется до 1 при отображении.

Вы можете увидеть истинные значения, добавив .ToString("R")

person SLaks    schedule 24.05.2012
comment
Спасибо, Math.Pow(64, 1.0/3.0) возвращает 3,9999999999999996. - Это все объясняет - person SelvirK; 24.05.2012

dCubeRootOf64 % 1 = 1 возвращает 1 вместо 0; потому что Math.Pow(i64, 1.0 / 3.0) возвращает 3.9999999999999996, а 3.9999999999999996 % 1 возвращает 0.99999999999999956, что, в свою очередь, округляется до 1.

Таким образом результат 1.

person Rahul    schedule 24.05.2012
comment
@GrantWinney: Точно. 4.0%1 возвращает 0. - person SLaks; 24.05.2012
comment
Я только что попробовал тот же опубликованный код, и он дал 1 как o/p в рамках 3.5. - person Rahul; 24.05.2012
comment
@Рахул: Точно. Он должен вернуть 0. - person SLaks; 24.05.2012