Автор Тема: Ошибка в круглении ROUND  (Прочитано 1374 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Vint

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3276
  • Лечу куда хочу. cman 4.13.014x32, W10, W7
    • Просмотр профиля
Ошибка в круглении ROUND
« : Март 16, 2015, 04:18:20 pm »
Пример:
Код: Clickermann
  1. print(round(4.115, -2))
  2. print(round(4.125, -2))
  3. print(round(4.135, -2))
  4. print(round(4.145, -2))
  5. 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


Vint

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

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


Cleoss

  • Активный участник
  • ***
  • Сообщений: 251
  • Автоматизируй это!
    • Просмотр профиля
Re: Ошибка в круглении ROUND
« Ответ #2 : Февраль 21, 2019, 04:35:51 pm »
Автор кудат пропал по ходу?

Лог:
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?

ikhmelin

  • Зашел в гости
  • *
  • Сообщений: 2
    • Просмотр профиля
Re: Ошибка в круглении ROUND
« Ответ #3 : Февраль 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

  • Супермодератор
  • Герой форума
  • *
  • Сообщений: 3527
  • Котэ
    • Просмотр профиля
Re: Ошибка в круглении ROUND
« Ответ #4 : Февраль 26, 2019, 06:59:41 am »
На моем компьютере (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

ikhmelin

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