Надежный кубический корень в Haskell

Это зависит главным образом от того, насколько репозиторий используется. С одним пользователем, регистрирующимся один раз в день и операцией ответвления/слияния/и т.д. один раз в неделю, Вы, вероятно, не должны выполнять его несколько раз год.

С несколькими дюжинами разработчиков, работающих над несколькими дюжинами проектов каждая проверка в 2-3 раза в день, Вы могли бы хотеть выполнить его ночью.

не повредит выполнять его более часто, чем необходимый, все же.

то, Что я сделал бы, выполняется это теперь, затем неделя с этого времени проводит измерения использования диска, выполняет его снова и измеряет использование диска снова. Если это отбрасывает 5% в размере, то выполненный это один раз в неделю. Если это отбрасывает больше, то выполненный это более часто. Если это отбрасывает меньше, то выполненный это менее часто.

6
задан iCodez 22 January 2015 в 18:45
поделиться

3 ответа

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

Прежде всего, чтобы исправить вашу ошибку типа, вам нужно переопределить isCube . Если вы проверите его подпись типа, она будет выглядеть так:

isCube :: (RealFrac a, Floating a) => a -> Bool

Обратите внимание, что он ожидает что-то, что относится к классу Floating в качестве своего первого аргумента. Ваша проблема в том, что вы хотите использовать эту функцию для целочисленных значений, а целые числа не являются экземпляром Floating . Вы можете переопределить isCube следующим образом, чтобы выполнить проверку типа функции.

isCube x = isInt $ (fromIntegral x) ** (1/3)

Однако это не сделает вашу программу правильной.

Один из способов сделать вашу программу более правильной - это сделать то, что предложил Хенрик. Это будет выглядеть так:

isCube x = (round (fromIntegral x ** (1/3))) ^ 3 == x

Удачи!

8
ответ дан 9 December 2019 в 20:45
поделиться

Я мало что знаю о Haskell, но я бы взял кубический корень, округлил его до ближайшего целого числа, взял куб и сравнил с исходным значением.

3
ответ дан 9 December 2019 в 20:45
поделиться

perms имеет тип [Integer] . isCube имеет тип (RealFrac a, Floating a) => a -> Bool (как вы можете проверить в GHCI). Ограничение RealFrac происходит от раунда x , ограничение Floating происходит от x ** (1/3) . Поскольку Integer не является ни RealFrac , ни Floating , isCube не может использоваться как Integer -> Bool . Итак, фильтр isCube (perms n) не имеет смысла.

Поэтому вам нужно исправить isCube , чтобы он работал правильно с Integer s:

isCube x = isInt $ (fromInteger x)**(1/3)

Фактически, причина того, что isCube (384 ^ 3) даже компилируется, заключается в том, что он "действительно" означает isCube ((fromInteger 384) ^ (fromInteger 3)) .

Конечно, это все равно будет плохо работать из-за ошибок с плавающей запятой. По сути, проверка плавающих чисел на равенство, как в isInt , почти всегда является плохой идеей. См. Другие ответы, чтобы узнать, как улучшить тест.

0
ответ дан 9 December 2019 в 20:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: