Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > atoi/atof

Reply
Thread Tools

atoi/atof

 
 
debjyoti@gmail.com
Guest
Posts: n/a
 
      11-14-2008
Hi all

I was messing around with a perl script and realized converting
strings to integers/floats is iffy on perl (compared to C). There is
all this mention of atoi/atof being system dependent etc and so I
found this piece of code for atoi():

sub atoi {
my $t;
foreach my $d (split(//, shift())) {
$t = $t * 10 + $d;
}
return $t;
}

http://perl.plover.com/IAQ/IAQlist.h...ng_to_a_number

It worked for my applicaton and then I needed an atof(). It was easy
to enhance the above:

sub atof {
my $pre;
my $suf;
my $t;

$in = shift();
@dual = split(/\./,$in );
foreach my $d (split(//, $dual[0])) {
$pre = $pre * 10 + $d;
}
$div = 1;
foreach my $d (split(//, $dual[1])) {
$suf = $suf * 10 + $d;
$div *= 10;
}

$t = $pre + ($suf/$div);
#print "!!!debug!!! $in $dual[0] , $dual[1] [$pre + ($suf / $div) =
$t]\n";
return $t;
}

Putting it here incase it is useful to some perl newbie... and in case
I need it future
 
Reply With Quote
 
 
 
 
Charlton Wilbur
Guest
Posts: n/a
 
      11-14-2008
>>>>> "d" == debjyoti <(E-Mail Removed)> writes:

d> Hi all I was messing around with a perl script and realized
d> converting strings to integers/floats is iffy on perl (compared
d> to C).

String to integer:

my $out = int ($in);

String to float:

my $out = $in;

(Hint: the website you refer to -- http://perl.plover.com/IAQ/IAQlist.html
-- is not meant to be taken entirely seriously. Read some of the other
questions and answers if you doubt me.)

Charlton


--
Charlton Wilbur
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      11-14-2008
(E-Mail Removed) wrote:
>I was messing around with a perl script and realized converting
>strings to integers/floats is iffy on perl (compared to C).


Really? I haven't noticed. And considering that Perl knows only scalars
(each of which has certain string, numerical, and boolean values) I
don't quite understand what problem you are tyring to solve.

>There is
>all this mention of atoi/atof being system dependent etc and so I
>found this piece of code for atoi():


>sub atoi {
> my $t;
> foreach my $d (split(//, shift())) {
> $t = $t * 10 + $d;
> }
> return $t;
>}


Is there anything wrong with just using $t in a numerical context, e.g.
adding 0?

>It worked for my applicaton and then I needed an atof(). It was easy
>to enhance the above:


Is there anything wrong with just using the scalar value in a numerical
context? (Well, I guess there could be due to the inherent problems of
floating point arithmetic)

>Putting it here incase it is useful to some perl newbie... and in case
>I need it future


Again, what problem exactly were you trying to solve where simply using
the scalar in the proper context didn't work?

jue
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      11-14-2008
On Thu, 13 Nov 2008 18:31:25 -0800 (PST), (E-Mail Removed) wrote:

>Hi all
>
>I was messing around with a perl script and realized converting
>strings to integers/floats is iffy on perl (compared to C). There is
>all this mention of atoi/atof being system dependent etc and so I
>found this piece of code for atoi():
>
>sub atoi {
> my $t;
> foreach my $d (split(//, shift())) {


Split() is being passed a string. So $d is now used as a string.
$t here is unknown at this point.

> $t = $t * 10 + $d;

^ ^
Now $t and $d are being used as a number because of the *+ operators.
If $d were not a digit, there might be a runtime error.

> }
> return $t;
>}
>

[snip]

Perl's got a kind of general purpose type SCALAR that interprets
if a number, string based on the usage of operators. Its interchangeable.
So its not really necessary to do this.

Of more use would be rounding in the conversion of float to int (both SCALARS).
Here you have to do it yourself. ie:
$needwholenumberrounded = int($floatnumber+.5);

In your examples you emulate the algorithym for the C atoi().
When in effect, Perl, built on C, calls atoi() directly from the standard runtime
libraries. So there's no need to duplicate the work.

I noticed in your emulation you don't account for [whitespaces][sign][digits].

Typically, atoi() from C library does something like this:

int _myatoi (char *p)
{
int num = 0, sign = 1, digit;
while (p && (digit=*p) == ' ' || digit == '\t') p++;
if (*p == '-') {
sign = -1;
p++;
} else
if (*p == '+')
p++;
while (digit = *p++) {
if (!(digit >= '0' && digit <= '9'))
return 0;
num = num * 10 + (digit - '0');
}
return sign*num;
}

Good job though, I like your emulations.


sln

 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      11-15-2008
On 2008-11-14 04:41, Jürgen Exner <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
>>I was messing around with a perl script and realized converting
>>strings to integers/floats is iffy on perl (compared to C).

>
> Really?


Yes, really. The Perl routines for converting between strings and
numbers are buggy.

> I haven't noticed.


I guess most people haven't, or the bugs would be fixed already. These
bugs have been there for a very long time, but they show up only if you
get close to the 15 digits/53 bits of FP precision.

I'm almost sure the OP's code is even buggier, though. String/number
conversions aren't trivial.

hp
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      11-15-2008
On Fri, 14 Nov 2008 17:48:16 GMT, (E-Mail Removed) wrote:

>On Thu, 13 Nov 2008 18:31:25 -0800 (PST), (E-Mail Removed) wrote:
>
>>Hi all
>>
>>I was messing around with a perl script and realized converting
>>strings to integers/floats is iffy on perl (compared to C). There is
>>all this mention of atoi/atof being system dependent etc and so I
>>found this piece of code for atoi():
>>
>>sub atoi {
>> my $t;
>> foreach my $d (split(//, shift())) {

>
>Split() is being passed a string. So $d is now used as a string.
>$t here is unknown at this point.
>
>> $t = $t * 10 + $d;

> ^ ^
>Now $t and $d are being used as a number because of the *+ operators.
>If $d were not a digit, there might be a runtime error.
>
>> }
>> return $t;
>>}
>>

>[snip]
>

[snip]
I might as well be correct
>
>Typically, atoi() from C library does something like this:
>
>int _myatoi (char *p)
>{
> int num = 0, sign = 1, digit;

// assert(p);
if (!p) return 0;
while ((digit=*p)&& (digit == ' ' || digit == '\t')) p++;
if (digit == '-') {
sign = -1;
p++;
} else
if (digit == '+')
p++;
> while (digit = *p++) {
> if (!(digit >= '0' && digit <= '9'))
> return 0;
> num = num * 10 + (digit - '0');
> }
> return sign*num;
>}
>
>Good job though, I like your emulations.
>
>
>sln


 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      11-16-2008
On Sat, 15 Nov 2008 19:37:00 +0100, "Peter J. Holzer" <(E-Mail Removed)> wrote:

>On 2008-11-14 04:41, Jürgen Exner <(E-Mail Removed)> wrote:
>> (E-Mail Removed) wrote:
>>>I was messing around with a perl script and realized converting
>>>strings to integers/floats is iffy on perl (compared to C).

>>
>> Really?

>
>Yes, really. The Perl routines for converting between strings and
>numbers are buggy.
>
>> I haven't noticed.

>
>I guess most people haven't, or the bugs would be fixed already. These
>bugs have been there for a very long time, but they show up only if you
>get close to the 15 digits/53 bits of FP precision.
>
>I'm almost sure the OP's code is even buggier, though. String/number
>conversions aren't trivial.
>
> hp


">>>strings to integers/floats is iffy on perl (compared to C). "

Aren't trivial? So ANSI C++ hasn't got it right yet? Perl had to bypass.
Its the other way around, number to string isin't trivial.


sln

 
Reply With Quote
 
Ilya Zakharevich
Guest
Posts: n/a
 
      11-16-2008
[A complimentary Cc of this posting was sent to
<(E-Mail Removed)>], who wrote in article <(E-Mail Removed)>:
> On Sat, 15 Nov 2008 19:37:00 +0100, "Peter J. Holzer" <(E-Mail Removed)> wrote:
> >I'm almost sure the OP's code is even buggier, though. String/number
> >conversions aren't trivial.


> ">>>strings to integers/floats is iffy on perl (compared to C). "


> Aren't trivial?


Yes.

> So ANSI C++ hasn't got it right yet?


What has C++ got to do with it? (And which particular runtime library
would you mean anyway? AFAIK, ANSI does not produce any compiler...)

> Perl had to bypass.


For some unfathomable reasons, Perl (starting from about 5.8.1?)
bypasses CRTL routines...

> Its the other way around, number to string isin't trivial.


??? Do not know what makes you think so. One is decimal-to-binary,
another is binary-to-decimal; both require higher precision (IIRC, 3
extra binary digits) than what the target conversion format can hold...

Yours,
Ilya
 
Reply With Quote
 
Peter J. Holzer
Guest
Posts: n/a
 
      11-17-2008
On 2008-11-16 21:06, (E-Mail Removed) <(E-Mail Removed)> wrote:
> On Sat, 15 Nov 2008 19:37:00 +0100, "Peter J. Holzer" <(E-Mail Removed)> wrote:
>>On 2008-11-14 04:41, Jürgen Exner <(E-Mail Removed)> wrote:
>>> (E-Mail Removed) wrote:
>>>>I was messing around with a perl script and realized converting
>>>>strings to integers/floats is iffy on perl (compared to C).
>>>
>>> Really?

>>
>>Yes, really. The Perl routines for converting between strings and
>>numbers are buggy.
>>
>>> I haven't noticed.

>>
>>I guess most people haven't, or the bugs would be fixed already. These
>>bugs have been there for a very long time, but they show up only if you
>>get close to the 15 digits/53 bits of FP precision.
>>
>>I'm almost sure the OP's code is even buggier, though. String/number
>>conversions aren't trivial.
>>
>> hp

>
> ">>>strings to integers/floats is iffy on perl (compared to C). "
>
> Aren't trivial? So ANSI C++ hasn't got it right yet?


"ANSI C++" is a specification. It only defines what needs to be done,
not how to do it. You would have to look at specific implementations.
Anyway, C++ is irrelevant here, as perl is written in C, not C++.

> Perl had to bypass.


ANSI C has a strtod function for string -> floating point conversion.
I'm not sure if perl uses it (it's been some time since I looked at the
code, sorry), but it probably could and should use it, as I would expect
it to be correct on all major platforms. If perl doesn't use it, it is
probably for historical reasons. Easy to fix.

Unfortunately, there is no reverse function in C: sprintf generates a
fixed number of digits after the decimal point, which is either too
little or too much. So that's something perl has to do itself.

> Its the other way around, number to string isin't trivial.


Conversion to and from integers is trivial (typical exercise for first
semester students). Conversion to and from FP numbers isn't trivial in
either direction. The situation is only asymmetric because C already has
a nice function for conversion from strings to numbers (which shields
the C programmer from all the hairy stuff), but not for the
reverse.

hp
 
Reply With Quote
 
Ilya Zakharevich
Guest
Posts: n/a
 
      11-17-2008
[A complimentary Cc of this posting was NOT [per weedlist] sent to
Peter J. Holzer
<(E-Mail Removed)>], who wrote in article <(E-Mail Removed)>:
> ANSI C has a strtod function for string -> floating point conversion.
> I'm not sure if perl uses it (it's been some time since I looked at the
> code, sorry), but it probably could and should use it, as I would expect
> it to be correct on all major platforms. If perl doesn't use it, it is
> probably for historical reasons. Easy to fix.


In fact, this particular misfortune is quite recent. Somebody did not
realize that the question is tricky, and inserted a wrong, homegrown,
implementation...

> Unfortunately, there is no reverse function in C: sprintf generates a
> fixed number of digits after the decimal point, which is either too
> little or too much. So that's something perl has to do itself.


Nope, Perl's semantic coincides (unfortunately!) with sprintf()'s
one. It may have its own implementation of sprintf(), but no more
than that...

The alternative semantic (emit as few digits as the string==>number
function requires to reproduce the same number) is computationally
intensive. When, in 90's, a replacement was discussed, it led to
significant slowdowns. However, nobody at the moment realized that
Perl was not caching N-->S conversion agressively enough, so it was
repeating the conversion again and again. When later I found/fixed
the caching problem, the benchmarks were not (AFAIK) redone..

The third problem is that one wants to minimize loads on
newsgroup/mailing-list "why numeric calculations are so weird in
Perl"; so the precision of N-->S is deliberately chosen so low, that
indications of weirdness of FP arithmetic are not manifested as often
as it would be with "precise" algorithms...

Hope this helps,
Ilya
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments