Author Topic: Ошибка в круглении ROUND  (Read 4338 times)

0 Members and 1 Guest are viewing this topic.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Ошибка в круглении ROUND
« on: March 16, 2015, 04:18:20 PM »
Пример:
Code: (clickermann) [Select]
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))

Лог:
Code: [Select]
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


Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: Ошибка в круглении ROUND
« Reply #1 on: March 16, 2015, 05:09:19 PM »
это не ошибка, это -  небольшая чётная вариативность функции округления.  :'(
Какая же это "чётная вариативность", если в справке чётко сказано:
Quote
Примечания
Округление происходит в сторону от нуля. То есть prec = 2 округлит число до сотен, а prec = -2 до сотых (два знака после точки). Откругление происходит по стандартному правилу 0.5

Я конечно в курсе, что в некоторых языках это нафиг никому не нужно приводить в порядок. Типа "банковское округление" + погрешность чисел с плавающей запятой. Но я думал здесь ROUND ручками прописан правильно, а не просто ретранслирован из Делфи.
Тем более, что некоторые варианты, которые должны давать неправильное округление, дают таки правильное и наоборот.
« Last Edit: March 16, 2015, 05:14:00 PM by Vint »


Cleoss

  • Активный участник
  • ***
  • Posts: 260
  • Автоматизируй это!
    • View Profile
Re: Ошибка в круглении ROUND
« Reply #2 on: February 21, 2019, 04:35:51 PM »
Автор кудат пропал по ходу?

Лог:
Code: [Select]
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) так и не нашлось:

Вот какие варианты пробовал:

От Винта!))
Code: [Select]
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

Code: [Select]
// 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

Code: [Select]
// 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

Code: [Select]
// 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?

ikhmelin

  • Зашел в гости
  • *
  • Posts: 2
    • View Profile
Re: Ошибка в круглении ROUND
« Reply #3 on: February 26, 2019, 05:50:49 AM »
На моем компьютере (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


Oraven

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3685
  • Котэ
    • View Profile
Re: Ошибка в круглении ROUND
« Reply #4 on: February 26, 2019, 06:59:41 AM »
На моем компьютере (windows 10, 64 бита) неправильно работает функция round в последней версии программы -- в том числе в прилагаемом к программе "большом" тесте. Результат оказывается умноженным на 1000 или что-то в этом роде. Прилагаю код и результаты.

В последней это какой?
Win 10, 64 bit : Clickermann v4.13.014, 64 bit

Запускаю твой код и вот результат
Code: [Select]
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

ikhmelin

  • Зашел в гости
  • *
  • Posts: 2
    • View Profile
Re: Ошибка в круглении ROUND
« Reply #5 on: February 27, 2019, 05:13:20 AM »
Именно этот. Я разобрался -- накладка была в том, что round использует определения символов-разделителей из Windows, в отличие от функции int и от самого кликера. У меня была определена десятичная запятая, а точка -- разделитель тысяч. В результате round воспринимала 1.1234 ка целое 11234 и т.п. Так что round не согласуется со всем остальным... Причем результат на 32bit и 64bit версиях кликера один и тот же.
« Last Edit: February 27, 2019, 05:25:39 AM by ikhmelin »