1

我有一个关于将$calc值从科学计数法转换为十进制的问题。请问有什么想法吗?

my $calc = log2($prob/$probWords);

push @result, join(' ',@words) ." (".$calc.")\n";

if(scalar(@result) == $bloc)
{
  $cmp += $bloc;
  print "$cmp lignes traités\n";
  writeToResultFile($outFile,@result);
  @result = ();
}
4

3 回答 3

9

您可以使用sprintf将您的数字转换为字符串并给它一个具体的格式。例子:

# Round number to 5 digits after decimal point
$calc_str = sprintf("%.5f", $calc);
于 2013-03-30T08:32:16.300 回答
2

Alois Mahdal 走在正确的轨道上,但很难解决问题。这是对此事的不同看法。我们可以使用 Devel::Peek 来查看 Perl 在变量中看到的内容。Perl 具有三种与 C 类型相关的基本(非引用)存储类型:字符串是指针(PV),数字可以是浮点数(NV,数值)或整数(IV)。

#!/usr/bin/env perl

use strict;
use warnings;

use Devel::Peek; # Dump

my $x = "1e10";
Dump $x;

输出

SV = PV(0x1204090) at 0x1225b80
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x1212ac0 "1e10"\0
  CUR = 4
  LEN = 16

PV 是一个字符串。你可以看到价值。现在我们强制输入一个数字,比如加零。

...
$x += 0;
Dump $x;

屈服

SV = PVNV(0xf018f0) at 0xf21b90
  REFCNT = 1
  FLAGS = (PADMY,IOK,pIOK)
  IV = 10000000000
  NV = 10000000000
  PV = 0xf0eac0 "1e10"\0
  CUR = 4
  LEN = 16

现在您可以看到该变量包含原始 PV 和代表 100 亿的数值 (NV)(以及整数值 (IV))。IOK 告诉我们它目前主要被认为是一个整数。它会保留其他值,以防您再次强制。

所以你看,从科学值到数字的强制转换就像从字符串转换为数字一样简单(加零是一种常见的机制)。反过来,请使用sprintf正确的格式。

注意为了完整起见,我们可以通过添加小数来查看到 NV 的转换。

...
$x += 0.1;
Dump $x;

输出

SV = PVNV(0x1ee0910) at 0x1f00b90
  REFCNT = 1
  FLAGS = (PADMY,NOK,pNOK)
  IV = 0
  NV = 10000000000.1
  PV = 0x1eedac0 "1e10"\0
  CUR = 4
  LEN = 16

NOK 告诉 Perl 它现在应该是一个浮点值。

于 2013-03-30T19:44:10.530 回答
1

虽然 Miguel 的答案似乎是您正在寻找的,但无论如何我都会提出一些理论:更正式的正确答案是: 您不能。 幸运的是,你不需要离开。

Perl 不使用变量存储符号。它是字符串还是数字都无关紧要:只要将任何符号的数字存储在字符串中,它就可以用作数字:

$a = "1e4";                             # $a now holds "1e4"
print $a . " (read 'one-e-four')\n";    # mentors on pronunciation
$a = $a / 1000;                         # $a now holds 10
$a = $a . "23";                         # $a now holds "1023" (or 1023 or even 1.023e3...)
$a = $a + 1;                            # $a now holds 1024 (or "1024")
print "Hello " . $a . " worlds\n";      # greets 1024 worlds

转换是隐式的。在上面的例子中:

  1. Perl 不知道 "1e4" 作为数字的含义,直到第 3 行,当它迅速将其计算为一万时,因此产生结果 10,在我的示例中,它被分配回$a. 现在存储的值是数字。

  2. 现在在下一行的字符串表达式中,十被解释为“10”(十进制是数值的默认表示法)。这两个字符串的连接产生字符串“1023”。

  3. 与除法相同的故事:“1023”出现在数字表达式中,因此必须转换为数字

但是,通常,您希望对转换有更多控制权。

  • 如果将 [what come in as] 字符串转换为 [what needs to be used as] 数字,典型的原因之一是您不能 100% 确定字符串形式的外观:特别是如果它来自用户,“输入号码”的答案可以是“100”,但也可以是“0100”、“百”或“你母亲的年龄”(相信我,有些用户可能真的很讨厌)。

    这就是正则表达式(或可能是其他技术)的用途。

  • 在另一种情况下,如果您想将该值用作字符串的一部分,您可能想确定数字的外观——将使用什么表示法或使用多少个字符。

    这就是sprintf 和 printf的用途。

由于 Perl 总是准备好将任何(数字/字符串)值解释为数字或字符串,因此您无需关心$a内部是数字还是字符串。另一方面,您仍然需要关心的是变量的内容

于 2013-03-30T15:53:11.253 回答