Автокликер Clickermann :: Форум
Основной раздел => Ошибки => Topic started by: Vint on March 16, 2015, 04:18:20 PM
-
Пример:
print(round(4.115, -2))
print(round(4.125, -2))
print(round(4.135, -2))
print(round(4.145, -2))
print(round(4.155, -2))
Лог:
16:15:33 4.12
16:15:33 4.13
16:15:33 4.13
16:15:33 4.14
16:15:33 4.16
-
это не ошибка, это - небольшая чётная вариативность функции округления. :'(
Какая же это "чётная вариативность", если в справке чётко сказано:
Примечания
Округление происходит в сторону от нуля. То есть prec = 2 округлит число до сотен, а prec = -2 до сотых (два знака после точки). Откругление происходит по стандартному правилу 0.5
Я конечно в курсе, что в некоторых языках это нафиг никому не нужно приводить в порядок. Типа "банковское округление" + погрешность чисел с плавающей запятой. Но я думал здесь ROUND ручками прописан правильно, а не просто ретранслирован из Делфи.
Тем более, что некоторые варианты, которые должны давать неправильное округление, дают таки правильное и наоборот.
-
Автор кудат пропал по ходу?
Лог:
16:15:33 4.12
16:15:33 4.13
16:15:33 4.13
16:15:33 4.14
16:15:33 4.16
Это конечно классика, но у меня щас не получилось воспроизвести этот баг, ни в версии 4.12, ни в 4.13, ни в 4.14 тем более (стоит Вин10, которая с год не обновлялась). Джонни там вродь писал, что математику поправил, но чтот у меня ощущение, что здесь идёт зависимость вычислений от какихт системных либ типа C Redistributable или .NET framework. Сам промурыжился с час тестов в поисках неправильных округлений, но результатов (найденных ошибок с этим вашим IEEE-754) так и не нашлось:
Вот какие варианты пробовал:
От Винта!))
print(round(4.115, -2))
print(round(4.125, -2))
print(round(4.135, -2))
print(round(4.145, -2))
print(round(4.155, -2))
halt
// 21.02.2019
#name "ieee754"
logclear
$a=0.0001
$b=0.01
$incr=0.0001
$lim=1
$round="0000"
$lvl=-2
for($a,$a<$lim,$incr)
for($precis=-4,$precis<4)
$g=round($a,$precis)
if(strpos($g,$round)>0)
print(" a = ",$a, ", $g = ",$g, ", precis = ",$precis)
end_if
end_cyc
end_cyc
for($h=0,$h<1000)
for($precis=-4,$precis<1)
$hh=round($h,$precis)
if($h=int($hh))
//
else
print(" h = ",$h, ", hh = ",$hh, ", precis = ",$precis)
end_if
end_cyc
end_cyc
print(0.1+0.2)
print(round(0.1+0.2,-4))
halt
// 21.02.2019
#name "ieee754"
logclear
$a=0.0001
$b=0.01
$incr=0.0001
$lim=1
$round="0000"
$lvl=-2
for($a,$a<$lim,$incr)
for($precis=-4,$precis<4)
$g=round($a,$precis)
if(strpos($g,$round)>0)
print(" a = ",$a, ", $g = ",$g, ", precis = ",$precis)
end_if
end_cyc
end_cyc
halt
// 21.02.2019
#name "ieee754"
logclear
$a=0.01
$b=0.01
$incr=0.01
$lim=100
$round="0000"
$lvl=-2
for($a,$a<$lim,$incr)
for($b,$b<$lim,$incr)
$c=$a/$b
$d=$a*$b
$e=$a-$b
$f=$a+$b
$aa=round($a,$lvl)
$cc=round($c,$lvl)
$dd=round($d,$lvl)
$ee=round($e,$lvl)
$ff=round($f,$lvl)
if(strpos($c,$round)>0)
print(" c = ",$a, " / ",$b," = ",$c)
end_if
if(strpos($d,$round)>0)
print(" d = ",$a, " * ",$b," = ",$d)
end_if
if(strpos($e,$round)>0)
print(" e = ",$a, " - ",$b," = ",$e)
end_if
if(strpos($f,$round)>0)
print(" f = ",$a, " + ",$b," = ",$f)
end_if
//waitms(100)
if(strpos($aa,$round)>0)
print(" aa = ",$aa)
end_if
if(strpos($cc,$round)>0)
print(" cc = ",$a, " / ",$b," = ",$cc)
end_if
if(strpos($dd,$round)>0)
print(" dd = ",$a, " * ",$b," = ",$dd)
end_if
if(strpos($ee,$round)>0)
print(" ee = ",$a, " - ",$b," = ",$ee)
end_if
if(strpos($ff,$round)>0)
print(" ff = ",$a, " + ",$b," = ",$ff)
end_if
end_cyc
end_cyc
halt
Надеюсь, нигде в методиках не повторился. Так что возможно Джонни действительно пофиксил тему, вот только странно, что баг на 4,12 не возник, или может он у меня был на 4,11?
-
На моем компьютере (windows 10, 64 бита) неправильно работает функция round в последней версии программы -- в том числе в прилагаемом к программе "большом" тесте. Результат оказывается умноженным на 1000 или что-то в этом роде. Прилагаю код и результаты.
print(ROUND(1236, 1)) // $r = 1240
print(ROUND(1236, 2)) // $r = 1200
print(ROUND(1.236, -2)) // $r = 1.24
print(ROUND(1.236, -1)) // $r = 1.2
print(ROUND(1.236, 0)) // $r = 1
print(ROUND(1.2368, -2)) // $r = 1.24
print(ROUND(1.2368, -1)) // $r = 1.2
print(ROUND(1.2368, 0)) // $r = 1
*************************************
02:38:23 1240
02:38:23 1200
02:38:23 1236
02:38:23 1236
02:38:23 1236
02:41:36 12368
02:41:36 12368
02:41:36 12368
-
На моем компьютере (windows 10, 64 бита) неправильно работает функция round в последней версии программы -- в том числе в прилагаемом к программе "большом" тесте. Результат оказывается умноженным на 1000 или что-то в этом роде. Прилагаю код и результаты.
В последней это какой?
Win 10, 64 bit : Clickermann v4.13.014, 64 bit
Запускаю твой код и вот результат
07:54:20 1240
07:54:20 1200
07:54:20 1.24
07:54:20 1.2
07:54:20 1
07:54:20 1.24
07:54:20 1.2
07:54:20 1
-
Именно этот. Я разобрался -- накладка была в том, что round использует определения символов-разделителей из Windows, в отличие от функции int и от самого кликера. У меня была определена десятичная запятая, а точка -- разделитель тысяч. В результате round воспринимала 1.1234 ка целое 11234 и т.п. Так что round не согласуется со всем остальным... Причем результат на 32bit и 64bit версиях кликера один и тот же.