【问题标题】:How do I convert scientific to decimal notation?如何将科学记数法转换为十进制记数法?
【发布时间】:2013-03-30 08:02:31
【问题描述】:

我有一个关于将$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 = ();
}

【问题讨论】:

  • 使用 %f 格式的 printf?
  • @Barmar 如此接近,sprintf
  • 虽然从标题和问题文本来看,您的要求似乎很清楚,但我看不出代码 sn-p 与此有何关联。

标签: perl scientific-notation


【解决方案1】:

您可以使用sprintf 将您的号码转换为字符串并为其指定具体格式。示例:

# Round number to 5 digits after decimal point
$calc_str = sprintf("%.5f", $calc);

【讨论】:

    【解决方案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 它现在应该是一个浮点值。

    【讨论】:

    • 在看到删除的编辑后,我实际上很难不去(唤醒我 2 岁的小恶魔侄子)哈哈:D
    • @AloisMahdal,我要退出罢工,因为如果人们看到你的评论线程,这将有助于他们了解事件的时间表。恐怕唤醒 2yo 是你的问题:-P
    【解决方案3】:

    虽然 Miguel 的答案似乎正是您想要的,但我还是会提出一些理论:更正式的正确答案是:您不能。幸运的是,您不需要离开。

    Perl 不使用变量存储符号。不管是字符串还是数字都无所谓:只要 any 表示法中的数字存储在字符串中,它就可以用作数字:

    $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. 直到第 3 行,Perl 才知道“1e4”作为数字的含义,当它很快 将其视为一万,因此产生结果十,在我的示例中是 分配回$a。现在存储的值是数字。

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

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

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

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

      这就是regular expressions(或者可能是其他技术)的用途。

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

      这就是sprintf and printf 的用途。

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

    【讨论】:

    • 查看我的回答以了解更多关于内部发生的事情。
    猜你喜欢
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2018-11-27
    • 2012-11-29
    相关资源
    最近更新 更多