Что нового

Глюк в AutoIT?

mrPuh

Новичок
Сообщения
19
Репутация
0
Всем привет!

Подскажите кто глючит - я или AutoIT? )
Код:
Код:
$i = 5.4

$e = int($i / 5)
$i = $i - ($e * 5)

$e = int($i / 0.2)
$i = $i - ($e * 0.2)

ConsoleWrite($i)
MsgBox('','',$i)


Данный код должен вывести: 0.
Но он выводит: 3.33066907387547e-016

Как можно исправить?

AutoIT версия 3.3.14.5
 

Oki

Новичок
Сообщения
46
Репутация
1
Числа 5,4 и 0,2 преобразуются изначально в числа, приблизительно равные им, ввиду двоичного способа представления действительных чисел в компьютерах. Для работы с точными десятичными числами используются либо специальные библиотеки, либо собственные методы. В определённых случаях можно применять округление, когда заведомо известно, сколько десятичных цифр идёт после запятой. Также может быть полезен подход, при котором числа хранятся в виде целых, полученных домножением на 10 или другое круглое число (также при известном заранее виде десятичной записи чисел). Обычное присваивание переменным этого округления до ближайших двоичных чисел максимальной фиксированной точности избежать не может. Это только в десятичной записи эти два числа могут обойтись конечным числом цифр, в двоичной это периодические дроби с периодами, отличными от (0):
5,4 = 101,(0110) 2; 0,2 = 0,(0011) 2.

Кстати, тот же результат можно наблюдать даже при непосредственном выводе более простого выражения.
Код:
MsgBox(0, "", 5.4 - 5 - 2 * 0.2)
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
Код:
MsgBox(0, "", Int(5.4 - 5 - 2 * 0.2))
 
Последнее редактирование:

Oki

Новичок
Сообщения
46
Репутация
1
Код:
MsgBox(0, "", Int(5.4 - 5 - 2 * 0.2))
А ещё можно на 0 умножить с тем же результатом. Это не панацея. Нужно с некоторым пониманием того, что ожидается в результате, округления делать, о чём выше было сказано. В иной подобной ситуации можно и соседнее с требуемым целое число в результате получить, но это тоже не всегда означает, что вопрос только в том, какую из функций округления применить.
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,422
Репутация
597
Причем тут умножение на ноль? Если используешь int, то используй к каждому выражению. Справку смотрел по функции int? Там указано на некоторые особенности при работе с числами с плавающей точкой.
 

Oki

Новичок
Сообщения
46
Репутация
1
Причем тут умножение на ноль? Если используешь int, то используй к каждому выражению. Справку смотрел по функции int? Там указано на некоторые особенности при работе с числами с плавающей точкой.
А при чём тут функция Int и справка? Да, в некоторых случаях этот вариант может быть полезным (и мной это было отмечено в более развёрнутом виде), но применение должно быть осознанным и применимым к конкретным нуждам. Неизвестны прочие условия и потребности топикстартера. А написать строчку, заведомо выдающую 0, и тащиться с этого, понту нет. Ты же не знаешь, нужно ли в текущей задаче отличать 0 от 0,4, например. И даже в том случае, когда доподлинно известно, что результат должен быть целым, функция Int для округления в общем случае не годится. Справку по ней смотрел? Там описаны некоторые особенности.
 
Верх