ActiveState Perl 5.14 не может сравнить определенные значения? - PullRequest
1 голос
/ 24 февраля 2012

В основном, используя следующий код в файловом потоке, я получаю следующее:

$basis = $2 * 1.0;
$cost = ($basis - 2500.0) ** 1.05;
# The above should ensure that both cost & basis are floats
printf "  %f -> %f", $basis, $cost;
if ($basis gt $cost) {  # <- *** THIS WAS MY ERROR: gt forces lexical!
    $cost = $basis;
    printf " -> %f", $cost;
}

Выходы:

  10667.000000 -> 12813.438340
  30667.000000 -> 47014.045519
  26667.000000 -> 40029.842300
  66667.000000 -> 111603.373367 -> 66667.000000
  8000.000000 -> 8460.203780
  10667.000000 -> 12813.438340
  73333.000000 -> 123807.632158 -> 73333.000000
  6667.000000 -> 6321.420427 -> 6667.000000
  80000.000000 -> 136071.379474 -> 80000.000000

Как видите, для большинства значений код работает нормально.

Но для некоторых значений .... 66667, 80000 и некоторых других, ActivePerl 5.14 сообщает мне, что 66667> 1111603 !!!

Кто-нибудь знает что-нибудь об этом - или у меня есть альтернативный интерпретатор Perl, который я мог бы использовать (Windows). Потому что это смешно.

Ответы [ 3 ]

3 голосов
/ 24 февраля 2012

Первые несколько глав Изучение Perl прояснят это для вас.Скалярные значения могут быть либо строками, либо числами, либо обоими одновременно.Perl использует оператор, чтобы решить, как обращаться с ними.Если вы хотите делать числовые сравнения, вы используете операторы числовых сравнений.Если вы хотите выполнять сравнение строк, вы используете операторы сравнения строк.

Сами скалярные значения не имеют типа, несмотря на другие ответы и комментарии с использованием таких слов, как «float» и «cast».Это просто строки и цифры.

3 голосов
/ 24 февраля 2012

Вы используете лексическое сравнение вместо числового

$cost = ($basis - 2500.0) ** 1.05;
printf "  %f -> %f", $basis, $cost;
if ($basis > $cost) {
    $cost = $basis;
    printf " -> %f", $cost;
}

ps: исправлено, чтобы соответствовать обновленному вопросу

0 голосов
/ 24 февраля 2012

Не уверен, почему нужно сравнивать как лексическое, но вы можете форсировать его с помощью sprintf

$basis_real = sprintf("%015.6f",$basis);
$cost_real = sprintf("%015.6f",$cost);
printf "  %s -> %s", $basis_real, $cost_real;
if ($basis_real gt $cost_real) {
     $cost = $basis;
     printf " -> %015.6f", $cost;
}

Выход:

  00010667.000000 -> 00012813.438340
  00030667.000000 -> 00047014.045519
  00026667.000000 -> 00040029.842300
  00066667.000000 -> 00111603.373367
  00008000.000000 -> 00008460.203780
  00010667.000000 -> 00012813.438340
  00073333.000000 -> 00123807.632158
  00006667.000000 -> 00006321.420427 -> 00006667.000000
  00080000.000000 -> 00136071.379474

Причина, по которой вы потерпели неудачу, как вы заметили, лексическое сравнение выполняет сравнение символов с символами, поэтому, когда оно достигает десятичной точки в 6667., оно фактически находится в алфавитном порядке перед 111603., поэтому оно больше.

Чтобы это исправить, вы должны сделать все числа одинакового размера, особенно там, где расположены десятичные дроби. % 015 - это общий размер числа, включая точку и десятичные дроби.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...