CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
esponential

 



mickey0
Novice

Mar 20, 2009, 5:32 AM

Post #1 of 17 (1609 views)
esponential Can't Post

Hello,
i have a problem with perl. Se below.

Code
my $v =0; 
........................................
if ($_ =~ m/value = (\S+)/) {
$v = $1; // $1 take the right value eg. "e-33"
if ( $v < 1) { # it's not possible to do this. ERROR HERE
......................
}
//the file is:
..............
otherString value = e-30 otherString
otherString value = 4e-30 otherString
otherString value = 1e-20 otherString
.........................

I have to extract the value of field "value" in a file a compare it as it was a numerical. But the shell says that $v it's not numeric....

Is it possible?

thanks,[


(This post was edited by mickey0 on Mar 20, 2009, 9:20 AM)


1arryb
User

Mar 20, 2009, 7:44 AM

Post #2 of 17 (1606 views)
Re: [mickey0] esponential [In reply to] Can't Post

Hi mickey0,

Of course! It's Perl. Aside from the java-y comment character ('//'), your code looks like it might work. What exactly is your problem?

Cheers,

Larry


mickey0
Novice

Mar 20, 2009, 9:19 AM

Post #3 of 17 (1602 views)
Re: [1arryb] esponential [In reply to] Can't Post


In Reply To
Hi mickey0,

Of course! It's Perl. Aside from the java-y comment character ('//'), your code looks like it might work. What exactly is your problem?

Cheers,

Larry

the problem is that it doesn't work!
As I explained above the error is :
Argument "0.42," isn't numeric in numeric lt (<)

the "//" isn't inside the script perl. There, i showed you how my input file is...

thanks


1arryb
User

Mar 20, 2009, 9:38 AM

Post #4 of 17 (1597 views)
Re: [mickey0] esponential [In reply to] Can't Post

Hi mickey0,

Ah, missed that. Ok, in order to do a numeric test on a value expressed in scientific notation, you'll have to convert it to decimal form. Perl won't do it for you:

Code
my $e = "3.4e-10"; 
my $d = sprintf("%f", $e);
if ( $d < 1 ) {
print "$e < 1\n";
}


Cheers,

Larry


mickey0
Novice

Mar 20, 2009, 9:50 AM

Post #5 of 17 (1594 views)
Re: [1arryb] esponential [In reply to] Can't Post

not to be rude but I got the same error.... this time on sprintf


(This post was edited by mickey0 on Mar 20, 2009, 9:50 AM)


1arryb
User

Mar 20, 2009, 10:15 AM

Post #6 of 17 (1589 views)
Re: [mickey0] esponential [In reply to] Can't Post

Hi mickey0,

You're right! The problem is the magnitude of your numbers. Regular perl floats (and sprintf) bottom out at about e-7. You'll have to use Math::BigFloat. Try this:

Code
Use Math::BigFloat; 

my $v =0;
........................................
if ($_ =~ m/value = (\S+)/) {
$v = $1; // $1 take the right value eg. "e-33"
my $f = Math::BigFloat->new($v);
if ( $f < 1) { # Should now work.
......................
}
//the file is:
..............
otherString value = e-30 otherString
otherString value = 4e-30 otherString
otherString value = 1e-20 otherString


UPDATE: I should mention that Math::BigFloat->new() will return 'NaN' (Not a Number) for your first sample line, since there is no mantissa in e-30, so you should check for that.

Larry


(This post was edited by 1arryb on Mar 20, 2009, 10:21 AM)


mickey0
Novice

Mar 20, 2009, 10:45 AM

Post #7 of 17 (1584 views)
Re: [1arryb] esponential [In reply to] Can't Post

nothing to do; "v" takes Nan:
my $temp = 0;
if ($_ =~ m/value = (\S+)/ ) {
$temp = $1;
my $v = Math::BigFloat->new($temp);
print "$v\n";
}

?.?


(This post was edited by mickey0 on Mar 20, 2009, 10:46 AM)


1arryb
User

Mar 20, 2009, 10:56 AM

Post #8 of 17 (1580 views)
Re: [mickey0] esponential [In reply to] Can't Post

mickey0,

Sorry, I don't understand '"v" takes Nan'. Are you saying you get '?.?' when you print Math::BigFloat->new('e-33')?

Larry


mickey0
Novice

Mar 20, 2009, 10:59 AM

Post #9 of 17 (1577 views)
Re: [1arryb] esponential [In reply to] Can't Post

sorry ?.? don't mean anything. The "print" prints "NaN"


1arryb
User

Mar 20, 2009, 11:08 AM

Post #10 of 17 (1576 views)
Re: [mickey0] esponential [In reply to] Can't Post

Hi mickey,

Yes, this is Math::BigFloat's way of telling you that you're giving it an invalid numeric string. As I said before, at least one line in your test data does not have any significant digits before the exponent part. You might check to see how that entry was created, but it's easy enough to work around it in your code:

Code
... 
my $v = Math::BigFloat->new($temp);
if ($temp eq 'NaN') {
print STDERR "$temp is not a valid number!\n";
} else {
...
}


Alternatively, if numbers like 'e-33' are rounding errors you can normalize them to zero:

Code
if ( $temp =~ /^e[+-]\d+/ ) { 
$temp = 0; # Rounding error, really zero.
}
...


Cheers,

Larry


mickey0
Novice

Mar 20, 2009, 11:23 AM

Post #11 of 17 (1573 views)
Re: [1arryb] esponential [In reply to] Can't Post

hello,
the problem is not that. I've written
$temp = 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000001;

and it is converted perfectly


mickey0
Novice

Mar 20, 2009, 11:34 AM

Post #12 of 17 (1571 views)
Re: [mickey0] esponential [In reply to] Can't Post

I found out that if I put
$temp = "1e-200";
it's work. Without 1 it doens't work.

- How can I concat "1" to $1

I don't know if it'll work because in my file only a number hasn't a digit in front of 'e'. So I should see the other results fine....

thanks

-----------------------------EDIT------------------------------------------
l

then i don't understand anyithing anymore:
this work:
$temp = "1e-200";
print $temp; # temp is ok
my $v = Math::BigFloat->new($temp);
print $v; # good

this not:
$temp = "1$1";
print $temp; # temp is ok too!!!!
my $v = Math::BigFloat->new($temp);
print $v; # Nan


(This post was edited by mickey0 on Mar 20, 2009, 11:54 AM)


1arryb
User

Mar 20, 2009, 11:56 AM

Post #13 of 17 (1566 views)
Re: [mickey0] esponential [In reply to] Can't Post

mickey,

Perhaps I was unclear, I was just speculating how a value like 'e-33' got into your test data. Math::BigFloat won't round an initialization argument.

If 1 + the parsed value is what you need, it's easy:

Code
$temp = "1$temp" if ( $temp =~ /^e[+-]\d+/ );


Larry


mickey0
Novice

Mar 20, 2009, 11:59 AM

Post #14 of 17 (1564 views)
Re: [1arryb] esponential [In reply to] Can't Post

hello,
I don't know if you read the post above. Anyway it doesn't work with
"1$1". it's a mistery.


1arryb
User

Mar 20, 2009, 12:22 PM

Post #15 of 17 (1561 views)
Re: [mickey0] esponential [In reply to] Can't Post

mickey,

Look for a bug in your latest program, not Math::BigFloat (hint: what is the value of $1 at '$temp = "1$1";')?

This is getting tiresome. I have tested the following program and it works. Please study it before replying.

Code
#!/usr/bin/perl 

use strict;
use warnings;
use Math::BigFloat;

open (IN, "< exponents.txt") or die "can't open exponents.txt for reading.";
while(my $line = <IN>) {
# Trim line termination.
$line =~ tr/\r\n//d;

# Get a number in exponential notation from line.
$line =~ m/value = (\S+)/;
my $v = $1;

# Handle parse errors.
die "can't parse \"$line\"" unless $v;

# Normalize bogus data to a value Math::BigFloat can handle
# AND that works for our application.
$v = "1$v" if $v =~ /^e-*\d+/;

# Get the value in numeric form.
my $d = Math::BigFloat->new($v);

# Test numeric value and do something.
if ( $d < 1) {
print ( "$v < 1, d=$d \n" );
} else {
print ( "$v >= 1, d=$d \n" );
}
}
close (IN);

exponents.txt contains:

Code
otherString value = e-30 otherString 
otherString value = 4e-30 otherString
otherString value = 1e-20 otherString
otherString value = e-200 otherString
otherString value = 3.2e23 otherString

If you run the program, you get:

Code
1e-30 < 1, d=0.000000000000000000000000000001 
4e-30 < 1, d=0.000000000000000000000000000004
1e-20 < 1, d=0.00000000000000000001
1e-200 < 1, d=0.000000000000000000000000000000000
00000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000
00000000000000000000000001
3.2e23 >= 1, d=320000000000000000000000


Larry


(This post was edited by 1arryb on Mar 20, 2009, 12:30 PM)


mickey0
Novice

Mar 21, 2009, 2:07 PM

Post #16 of 17 (1544 views)
Re: [1arryb] esponential [In reply to] Can't Post

!!!!!!
it was all right.
I didn't notice that in the file I have:

someString Value = e-200,
there was a comma at the end!!!!
I changed my code in this way (even I don't like so much):
if ($_ =~ m/Value = (\S+) /) {
my $v = substr $1, 0, length($1)-1;
# other stuff
....................................................
}


(This post was edited by mickey0 on Mar 21, 2009, 2:08 PM)


mickey0
Novice

Mar 23, 2009, 7:00 AM

Post #17 of 17 (1536 views)
Re: [mickey0] esponential [In reply to] Can't Post

Hello,
I found out that this way to extract the value is not ok.
I can instead extract it from another point of the file.
A line of file is now:

somestring someString {somestring} number value

I need to extract value that it's at the end of the variable $_
There is a way to do it very clean?

{somestring} = zero o more instances

thanks,


(This post was edited by mickey0 on Mar 23, 2009, 7:01 AM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives