f # целое число модуль с плавающей запятой 1,0 = 1,0? - PullRequest
0 голосов
/ 11 августа 2009

Хорошо, у меня есть две функции, первая из которых выглядит так:

let dlth x = float (x.ToString().Length)

, который принимает число с плавающей точкой и возвращает количество цифр, эта часть работает нормально. Вторая функция выглядит так:

let droot x = ((x ** (1./(dlth x))) % 1.)

, который принимает число с плавающей точкой и увеличивает его до степени, равной 1,0 / (количество цифр), затем берет результат и выполняет модуль 1,0. Который должен быть нулем для целого числа.

так для droot 36. требуется (36,0 ** (1,0 / 2,0)), что составляет 6,0, тогда 6,0 mod 1.0 равно 0,0;

Теперь, это прекрасно работает, вплоть до того, где я пробую номер 81.0. (и все числа выше 81, которые должны работать), который по какой-то причине возвращает 1.0, отбрасывая мое сопоставление с образцом. Кто-нибудь может сказать мне, почему это происходит?

PostScript: это часть решения Project Euler. Если вы знаете, какая проблема, пожалуйста, НЕ опубликуйте решение Project Euler. Мне просто нужна помощь, чтобы выяснить, почему модуль возвращает забавные результаты

Ответы [ 3 ]

8 голосов
/ 11 августа 2009

Арифметика с плавающей точкой таит в себе опасность на любом языке. На моей коробке

printfn "%f" (0.9999999999999 % 1.0)        

печать

1.000000

Надеюсь, это поможет вам в правильном направлении. Если вы действительно хотите узнать, является ли число с плавающей запятой "целым числом", то, например, вычитание ближайшего целого числа и проверка того, что абсолютное значение меньше некоторого эпсилона (например, 0,00001), является достойной ставкой

1 голос
/ 11 августа 2009

Если вы получаете неточности с плавающей точкой, вы можете понизить производительность с помощью типа данных .NET decimal (который может представлять все числа, представимые в base-10). Кроме этого используйте большую точность (double) или целочисленную математику.

0 голосов
/ 11 августа 2009

Я согласен с Брайаном, что полагаться на точное представление с плавающей запятой опасно, но я не могу воспроизвести вашу проблему. Для меня droot 81.0 дает ожидаемый результат 0.0. Какую версию F # вы используете? Вы работаете в .NET или Mono?

...