ActiveState Perl 5.14无法比较某些值?

时间:2012-02-24 05:03:08

标签: windows perl

基本上,在文件流上使用以下代码,我得到以下内容:

$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&gt; 1111603 !!!

有没有人知道这件事 - 或者我可以使用备用的Perl解释器(Windows)。因为这太荒谬了。

3 个答案:

答案 0 :(得分:3)

您正在使用词汇比较而不是数字比较

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

ps:修订以匹配更新的问题

答案 1 :(得分:3)

Learning Perl 的前几章将为您清除这一点。标量值可以是字符串或数字,也可以是两者同时出现。 Perl使用运算符来决定如何对待它们。如果要进行数值比较,可以使用数字比较运算符。如果要进行字符串比较,可以使用字符串比较运算符。

标量值本身没有类型,尽管其他答案和注释使用“float”和“cast”之类的单词。它只是字符串和数字。

答案 2 :(得分:-1)

不确定为什么你需要比较作为词汇,但你可以使用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是数字的总大小,包括句点和小数。