2013-03-30 2 views
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 =(); 
} 
+0

Использовать printf с форматом% f? – Barmar

+0

@Barmar so close, 'sprintf' – gaussblurinc

+0

Хотя из заголовка и текста вопроса кажется вполне понятным, что вы спрашиваете, я не вижу, как это относится к фрагменту кода. –

ответ

9

вы можете использовать sprintf для преобразования числа в строку и дать ему конкретный формат. Пример:

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

Хотя ответ Мигель, кажется, что вы ищете, я брошу в какой-то теории так или иначе: более формально правильный ответ был бы: Вы не можете. К счастью, вам не нужно бежать.

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, когда он быстро считает, что это, как десять тысяч, поэтому приносит результат десять, что в моем примере это уступленные назад к $a. Теперь сохраненное значение является числовым.

  2. Теперь в строчном выражении на следующей строке десять интерпретируется как «10» (десятичная цифра является обозначением по умолчанию для числовых значений). Конкатенация этих двух строк дает строку «1023».

  3. Та же история, как с делением: «1023» появится в числовом выражении, следовательно, должны быть преобразованы на номер

Обычно, однако, вы хотите иметь больше контроля над преобразованием.

  • В случае преобразования [что пришел в качестве] строки, чтобы [что должно быть использовано в качестве] числа, одна из типичных причин является то, что вы не уверены на 100%, как форма строка будет выглядеть например: , особенно если он поступает прямо от пользователя, ответ на «ввод номер» может быть «100», но может быть быть также «0100», «сто» или «возраст вашей матери» (поверьте, некоторые пользователи могут быть действительно противный).

    Вот что такое regular expressions (или, возможно, другие методы).

  • В другом случае, если вы хотите использовать это значение как часть строки, вы можете быть уверенным, как будет выглядеть номер - какие обозначения или сколько символов будут использоваться.

    Вот что такое sprintf and printf для.

Поскольку Perl всегда готов интерпретировать любое значение (числовое/строка) как число или строка, вам не нужно заботиться о том, $a внутренне числовое или строковое. На другом руке, вам все равно нужно заботиться о содержание ваших переменных.

+0

См. Мой ответ, чтобы узнать больше о том, что происходит внутри страны. –

2

Алоис Махдал находится на правильном пути , но с трудом работает с изгибами. Вот другое дело по этому вопросу. Мы можем использовать 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 

П.В. является строкой. Вы можете увидеть значение. Теперь мы принуждаем к числу, например, добавляя ноль.

... 
$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 и числовое значение (NV) (а также целое число (IV)) составляет 10 млрд. IOK говорит нам, что в настоящее время он считается целым числом. Он сохраняет другие значения в случае, если вы захотите снова принудить вас.

Так вы видите, что принуждение от научного значения к числу так же просто, как преобразование из строки в число (добавление нуля - общий механизм). Чтобы перейти в другую сторону, используйте sprintf с соответствующим форматом.

N.B. Для полноты мы можем видеть преобразование в 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 

и норвежские кроны говорят Perl, что теперь должно быть значением с плавающей точкой.

+1

После того, как вы увидели редактирование забастовки, я на самом деле с трудом пытаюсь не просыпаться (разбудить моего двухлетнего племянника дьявола) LOL: D –

+0

@AloisMahdal, я оставляю забастовку, потому что если люди видят поток комментариев на вашем, это поможет им понять временные рамки событий. Пробуждение 2yo - ваша проблема, я боюсь :-P –