Reputation: 317
I have a question concerning converting $calc
value from scientific notation to decimal.
Any idea please?
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 = ();
}
Upvotes: 1
Views: 4016
Reputation: 20280
Alois Mahdal is on the right track, but having a hard time working out the kinks. Here is a different take on the matter. We can use Devel::Peek to see what Perl sees in the variable. Perl has three basic (non-reference) storage types, related to C types: strings are pointers (PV) and numbers can be either floats (NV, number value) or integers (IV).
#!/usr/bin/env perl
use strict;
use warnings;
use Devel::Peek; # Dump
my $x = "1e10";
Dump $x;
outputs
SV = PV(0x1204090) at 0x1225b80
REFCNT = 1
FLAGS = (PADMY,POK,pPOK)
PV = 0x1212ac0 "1e10"\0
CUR = 4
LEN = 16
PV is a string. You can see the value. Now it we coerce to a number, say by adding zero.
...
$x += 0;
Dump $x;
yielding
SV = PVNV(0xf018f0) at 0xf21b90
REFCNT = 1
FLAGS = (PADMY,IOK,pIOK)
IV = 10000000000
NV = 10000000000
PV = 0xf0eac0 "1e10"\0
CUR = 4
LEN = 16
Now you can see that the variable hold both the original PV and the number value (NV) (as well as a integer value (IV)) representing 10 billion. The IOK tells us that it is considered an integer primarily at the moment. It keeps the other values in case you should want to coerce again.
So you see, coercion from a scientific value to a number is as easy as converting from a string to a number (adding zero is a common mechanism). To go the other way, use sprintf
with a proper format.
N.B. For completeness, we can see the conversion to an NV by adding a decimal.
...
$x += 0.1;
Dump $x;
outputs
SV = PVNV(0x1ee0910) at 0x1f00b90
REFCNT = 1
FLAGS = (PADMY,NOK,pNOK)
IV = 0
NV = 10000000000.1
PV = 0x1eedac0 "1e10"\0
CUR = 4
LEN = 16
and NOK tells Perl that it should now be a floating point value.
Upvotes: 2
Reputation: 11253
While Miguel's answer seems to be what you're looking for, I'll throw in some theory anyway: more formally correct answer would be: You can't. Luckily you don't need to anway.
Perl does not store notation with the variable. It should not even matter if it's a string or number: as long as number in any notation is stored in a string, it can be used as a number:
$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
The conversion is implicit. In above example:
Perl does not wonder what "1e4" would mean as a number until line 3, when it quickly
reckons it as ten thousand, therefore yielding result ten, which in my example is
assigned back to $a
. Now the value stored is numeric.
Now in string expression on the next line, ten is interpreted as "10" (decimal is the default notation for numeric values). Concatenation of these two strings yields string "1023".
Same story as with the division: "1023" appears in numeric expression, therefore must be converted to number
Normally, however, you want to have more control about the conversion.
In case of conversion of [what came in as] string, to [what needs to be used as] number, one of typical reasons is that you are not 100% sure how the string form will look like: especially if it comes right from user, answer to "enter number" can be "100", but could be be also "0100", "hundred" or "your mother's age" (believe me, some users can be really nasty).
That's what regular expressions (or probably other techniques) are for.
In the other case, if you want to use the value as part of a string, you might want to be sure how the number will look like--what notation or how many characters will be used.
That's what sprintf and printf are for.
Since Perl is always ready to interpret any (numeric/string) value as number or string,
you do not need to care about whether $a
is internally numeric or string. On the other
hand, what you still need to care about is the content of your variables.
Upvotes: 1
Reputation: 13792
you could use sprintf to convert your number to string and give it a concrete format. Example:
# Round number to 5 digits after decimal point
$calc_str = sprintf("%.5f", $calc);
Upvotes: 9