2015-02-10 2 views
0

Я заметил, что метод formline в Perl 5 имеет какое-то странное действие. Если десятичное значение больше 0,5, оно округляется. Если десятичное значение меньше 0,5, оно округляется вниз. Но когда десятичное значение является точным 0,5, мы обычно должны округлять, но форма линии округляет значение.Perl5 formline округляет точное значение 0.5 не округляет

Кто-нибудь знает, если это ошибка или предопределенная? Благодарю.

ответ

4

В отсутствие конкретной демонстрации, я укажу на два вероятных преступников:

  1. «Обычно мы должны округлить» абсолютно неверно. Существует много различных систем округления. sprintf, например, использует округлые.

    $ perl -E'say sprintf "%1\$.1f => %1\$.0f", $_ for 3.5, 4.5, 5.5, 6.5' 
    3.5 => 4 
    4.5 => 4 
    5.5 => 6 
    6.5 => 6 
    
  2. Число вы думаете, имеет дробный компонент 5/10 фактически не из-за точности ошибки с плавающей точкой.

    Многие числа являются периодическими в двоичных выражениях, а периодические числа не могут быть точно сохранены как плавающие числа. Например, 1/10, 2/10, 3/10, 4/10, 6/10, 7/10, 8/10 и 9/10 все периодические в двоичном порядке, так же как 1/3 является периодическим по десятичной (и двоичный).

    5/10 на самом деле легко хранить как число с плавающей запятой (5/10 = 1/2 = 2 -1), но если вы получили число через арифметику, у вас может не быть 5/10 ,

    $ perl -E'$x += 0.01 for 1..50; say sprintf "%.40f", $x' 
    0.5000000000000002220446049250313080847263 
    
+0

Спасибо за ваше объяснение. С небольшим тестом, что я обнаружил, что formline также использует круглые-четные. Спасибо! – hugobetty

+0

Пожалуйста, помогите проверить ниже тестовый код и помочь ответить, если есть способ, которым мы можем управлять тем, какой метод округления использовать. Благодарю. '#!/Usr/bin/perl my $ format = '@ #######'; my $ var1 = '15334.5000'; my $ var2 = '15334.50001'; my $ var3 = '15335.5000'; my $ var4 = '15336.5000'; formline $ format, $ var1; print "var1 = $^A \ n"; $^A = ''; formline $ format, $ var2; print "var2 = $^A \ n"; $^A = ''; formline $ format, $ var3; print "var3 = $^A \ n"; $^A = ''; formline $ format, $ var4; print "var4 = $^A \ n"; ' – hugobetty

+0

Вы можете округлить значение, прежде чем передавать его в форму – ikegami