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 (1034 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 (1031 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 (1027 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 (1022 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 (1019 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 (1014 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 (1009 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 (1005 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 (1002 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 (1001 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 (998 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 (996 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 (991 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 (989 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 (986 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 (969 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 (961 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