[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Omaha.pm] Jay on IRC - print "$j " . int($j) . "\n"; # prints '14 13'
For the archive, here's me on IRC a year ago or something. #perl is
explaining perl and C black magic to me. There may or may not have
been a bug in my Perl / kernel installation...
That was one of those mind blowing mornings where perl was not doing
what I thought it should. :)
j
#perl: +ascent_ +phuct +nocarrier +Skunk
*** End of /NAMES list.
*** Channel Mode is +spmtnl 123 *** Channel created at Monday, April
16, 2001 5:48:56 AM
*** #perl You're not channel operator
*** Mode change "+v dferret" on #perl by Roderick
dferret: my $j = (log 16384) / (log 2);
dferret: print "$j " . int($j) . "\n"; # prints '14 13'
dferret: Whats up with that? If $j is really 13.9999999999 why
doesn't it print like that?
dferret: (Linux 2.4.17)
joe321: number_format($num, 2) == 12.34
joe321: oops
joe321: wrong language
Kyriel: Beat me, daddy, eight-to-the-bar.
Somni: perldoc -q decimal
Somni: and follow the perlop reference
dferret: I understand perldoc -q decimal. I don't understand why,
if $j is really 13.99999999999 when I do a print $j it prints "14"...?
dferret: If 'print $j' spit out 13.999999999999 I'd understand the
problem.
*** taer (~tdunn@adsl-64-175-241-190.dsl.sntc01.pacbell.net) has
joined channel #perl
*** Mode change "+v taer" on #perl by Roderick
Somni: dferret: because floating point numbers are imprecise
corwin_: [corwin@gw3 corwin]$ perl -le '$a = 13.99999999999; print
$a'
corwin_: 13.99999999999
cfedde: remember all that limit stuff from calculus? Well here
it is again.
Psyche^: they are precise... they're just not real numbers in the
mathematical sense :-)
Somni: the floating point value doesn't match the reality of the
calculation; I would call that imprecise
dferret: So you're saying that print might round a floating point
up to 14? I thought print would always print 13.9999999999 as
13.9999999999999, but I'm getting "14". I didn't think print would
round.
wadi3: how can I store the output of an sql statement in a $var?
cfedde: wadi3: read about the DBI
corwin_: beat me to it cfedde :-)
Psyche^: floats are computer numbers and not mathematical numbers.
you just expect too much from the poor things...
cfedde: dferret: perl -le 'my $j = (log 16384) / (log 2); print
"$j " . int($j)'
cfedde: 14 14
*** Signoff: taer (Ping timeout: 378 seconds)
dferret: I get '14 13' w/ Perl 5.8.0 on Linux 2.4.17
cfedde: perl -v -> This is perl, v5.8.2 built for i386-freebsd
dferret: Did I compile in the PRINT_FUNCTION_ROUNDS var? :p
Somni: I get 14 14 with 5.8.0 on Linux 2.4.22
Somni: dferret: it has nothing to do with print
Psyche^: 14 14 5.8.2 2.6.0t11
dferret: Must be a Linux bug. I'll email Linus. -grin-
*** Signoff: wadi3 ()
dferret: What do you mean it's not print? The only reason int($j)
would spit out 13 on my box is that $j is really 13.9999999999 but
print $j is showing 14 -- meaning that print is rounding, right? -
ponder-
Somni: dferret: print is how you happen to be stringifying the
number
Somni: it has to do with how computers deal with floating point
values
dferret: I expected it to stringify 13.999999999 as 13.9999999999,
not 14. I didn't know print would stringify upwards.
Somni: how have you determined 13.9999999999 is the correct
result? even bc says it's supposed to be 14.00000000000000000014
cfedde: dferret: there has to be something odd in the way that
your math libraries are working. Is your perl using some wierd
version of log?
dferret: I figured it must be slightly < 14 because int($j) spits
out 13. int() rounds down, right?
Somni: my TI-85 says it's 14
*** alkatraz (~ugh@ip68-9-124-191.ri.ri.cox.net) has joined channel
#perl
*** Mode change "+v alkatraz" on #perl by Roderick
dferret: How would I know what log perl is using?
Somni: int rounds towards zero, effectively; it just strips off
the integral part
cfedde: s/ingegral/fractional/
dferret: Right, do that's how I "deetermined" that it must be
13.9999999999 not 14.000000000001
Somni: integral, and returns it
*** Signoff: morfic (Quit: Leaving)
dferret: s/do/so/
*** morfic (~U3N@cs662583-130.satx.rr.com) has joined channel #perl
*** Mode change "+v morfic" on #perl by Roderick
Somni: dferret: what does bc or dc say?
dferret: ...err... command line? Can't find those commands.
(Excuse my ignorance.)
Somni: echo "l(16384) / l(2)" | bc -l
dferret: bc: command not found
Somni: write a C program then
cfedde: what kind of flakey linux distribution does not have bc?
Somni: #include <math.h>\n#include <stdio.h>\nint main ()
{ printf("%.20f\n", log(16384) / log(2)); return 1; }
Somni: or something to that effect
*** Signoff: zerologic (Read error: Connection reset by peer)
dferret: jhannah@hannibal:~/cgi-bin$ ./j
dferret: 14.00000000000000000000
Somni: is perl linked to the same libm your new program is?
*** Signoff: epyon_II (Ping timeout: 624 seconds)
*** tdunn (~tdunn@adsl-64-175-241-190.dsl.sntc01.pacbell.net) has
joined channel #perl
*** Mode change "+v tdunn" on #perl by Roderick
Somni: ldd j; ldd `which perl`
dferret: ldd shows both my perl and my new C prog are using the
exact same /lib/lib* files...
Somni: do you have Devel::Peek installed?
*** zubs (~zubz@user-0ccemmv.cable.mindspring.com) has joined channel
#perl
*** Mode change "+v zubs" on #perl by Roderick
dferret: yes...
zubs: if i want to find any of these characters \/:*?"<>| what
would the regex code look like?
Somni: perl -MDevel::Peek -wle '$j = log(16384) / log(2); Dump
($j);'
Somni: zubs: perldoc perlre, perldoc perlretut, perldoc perlrequick
*** Signoff: morfic (Quit: Leaving)
Somni: dferret: paste the result to knowpaced
knowpaced: I'm a pastebot! Paste stuff at http://pastebot.nd.edu/perl
zubs: thx
dferret: SV = PVNV(0x8165510) at 0x814bfb0
dferret: REFCNT = 1
dferret: FLAGS = (NOK,pIOK,pNOK)
dferret: IV = 13
dferret: NV = 14
dferret: PV = 0
Somni: ugh
dferret: What does that mean? -laugh-
dngor: dferret: Bzt.
corwin_: dferret: knowpaced
knowpaced: I'm a pastebot! Paste stuff at http://pastebot.nd.edu/perl
*** Signoff: tdunn (Ping timeout: 240 seconds)
*** Signoff: joe321 ()
*** Mode change "+l 121" on #perl by Roderick
Somni: dferret: at most it's proof your problem has nothing to
do with print
Somni: that perl is shoving two different values in the IV and
NV elements is a little odd
dferret: -ponder- We're way over my head here.
dferret grins
*** morfic (~U3N@cs662583-130.satx.rr.com) has joined channel #perl
*** Mode change "+v morfic" on #perl by Roderick
Psyche^: i get FLAGS = (NOK,pNOK) NV = 14
*** tdunn (~tdunn@adsl-64-175-241-190.dsl.sntc01.pacbell.net) has
joined channel #perl
Psyche^: why is IV set at all?
*** Mode change "+v tdunn" on #perl by Roderick
Somni: it's set on mine too
Somni: but to 14
Psyche^: your perl sucks, mine is better. bwuahahaha
*** Signoff: tdunn (Read error: Operation timed out)
Somni: heh
dferret: 5.8.0 problem?
Somni: dferret: nope
Somni: probably some combination of compile flags
Somni: paste perl -V output to knowpaced, that's PASTE TO KNOWPACED
knowpaced: I'm a pastebot! Paste stuff at http://pastebot.nd.edu/perl
knowpaced: "dferret" at 68.13.20.113 pasted "perl -V" at http://
pastebot.nd.edu:80/304
Somni: Psyche^: do you have uselongdouble defined in your perl -V?
Psyche^: uselongdouble=undef
Somni: dferret: that may be your culprit, though it's hard to say
Somni: you could try recompiling without it, upgrade to 5.8.2,
or just stick it out
Somni: I may compile a perl with it enabled to see if that's it
when I get back
cwilbur: evening all.
*** zubs has left channel #perl
dferret: I was justs surprised as all sheeot that it happened. I
thought print always printed whatever.... I guess something wacky
must be happening internally. Anyhoozit, I'll probaby just use
sprintf to turn 13.999999999999 into 14?
Somni: the value -is- 14, something is being miscalculated
internally
cwilbur: this sounds like a floating point rounding problem.
Somni: it did initially
cwilbur: though I have only skimmed about a page of scrollback.
Somni: but the IV for the value is 13, when every calculation
I've done makes it out as 14
Somni: and several versions of perl agree
Somni: anyways, afk, dinner
*** Signoff: Somni (dinner)
cwilbur: right, but if the floating-point math comes out to
13.999999, wouldn't the IV most appropriately be 13?
dferret: I don't know anything about IV, so w/ Somni gone talking
to me will be like talking to a wall. -grin-
cfedde: It appears that different implementations of the log
function over estemate or underestemate.
dferret: Ya, my mystery though was that print is printing 14, not
13.99999999999 like I'd expect.
dferret: perl -le 'my $j = (log 16384) / (log 2); print "$j " . int
($j)'
dferret: On my system that prints "14 13". Everyone else gets "14
14".
cfedde: yes. I was the silly person that pasted the command line
yuo just pasted back
dferret: My explanation is that $j is 13.9999999999999 so int
takes it to 13, which I expect. I didn't expect print to "round" to
14 though...? (I'm just recapping for cwilbur.)
cwilbur: well, the next question is, what's different about your
system?
cwilbur: (both my systems say 14 14.)
dferret: Somni's theory was that I have USE_LONG_DOUBLE compiled
into perl.
cwilbur: that could be.
cwilbur: neither of my systems have USE_LONG_DOUBLE compiled in.
cfedde: dferret: is this a perl that came with your distribution?
or did you compile it yourself?
dferret: ? I'm on perl 5.8.0. Is this something I should take the
time to actually formalize for Perl 5 porters?
dferret: This isn't my server -- I don't know what distro it is or
how Perl got on there. I can call the guy.
cfedde: don't worry about it.
cwilbur: it's probably worth documenting.
dferret: Is it a bug? I expected print to print 13.9999999999, but
maybe that was a bad assumption?
dferret: Maybe I should just learn that print might "round" too?
Or would that be a lesson that no one should learn?
cfedde: perl -le 'print 13.9999999999999, " ", 13.99999999999999'
cfedde: 13.9999999999999 14
cfedde: isn't that odd?
Psyche^: no, 14 is even.
cwilbur: print probably tries to do the right thing.
dferret: I get 13.9999999999999 13.99999999999999
cwilbur: having taken rounding error into account.
cfedde: Keep extending the 9s on the second one till you get 14
dferret: (Because of my USE_LONG_DOUBLE?)
Psyche^: same as cfedde here
cfedde: it's the default number template for printf
cfedde: because of USE_LONG_DOUBLE, yes
cfedde: s/f$//;
*** elkane (kane@phree.ne.client2.attbi.com) has joined channel #perl
*** Mode change "+v elkane" on #perl by Roderick
dferret: perl -le 'print 13.9999999999999999, " ",
13.99999999999999999'
dferret: 13.9999999999999999 14
dferret: Your cutoff is 14 9s, mine is 17?
cfedde: I guess that you win!
*** peanuter (worldapart@host-64-179-13-126.syr.choiceone.net) has
joined channel #perl
cwilbur: well, you're using long doubles.
*** Mode change "+v peanuter" on #perl by Roderick
dferret: So my log is rounding to a precision my print can't handle?
cfedde: dferret: no that's not it.
*** Signoff: jaredy (Quit: leaving)
cfedde: read the description of $# in perldoc perlvar
*** jaredy (~jaredy@dorms-pppoe-1-74-225.pittsburgh.resnet.pitt.edu)
has joined channel #perl
*** Mode change "+v jaredy" on #perl by Roderick
dferret: perldoc says: Use of $# is deprecated. -grin-
cfedde: but it gives you a hint about what is happening.
dferret: perl -e 'print $#' doesn't print anything
cfedde: perl's print is written in terms of printf. If your perl
defines USE_LONG_DOUBLE then it changes the number of digits that
print prints before rounding.
dferret: hmm... Why would you ever want print to round? Wouldn't
you want it to always print the full float? Rounding is for printf,
isn't it?
cfedde: perl -e 'printf "%5.2f %5.2f\n", 13.99, 13.999'
cfedde: perl's print rounds by default. cfedde: and
apparently USE_LONG_DOUBLE controls some aspect of it.
Leolo: purl, seen kismet
purl: kismet was last seen on #perl 4 hours, 31 minutes and 3
seconds ago, saying: Ok, IBMs little download dealio is.... weird
[Wed Dec 10 19:33:59 2003]
*** Signoff: elkane ()
dferret: Seems strange to me. I would think that print wouldn't
round by default so it would be easy to see the whole float.
dferret: perl -le 'my $j = (log 16384) / (log 2); printf("%
0.200f", $j)'
dferret:
13.999999999999999999132638262011596452794037759304046630859375000000000
000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000
arp: nice
cfedde: Where do you suppose accuracy of that number begins to
falter?
dferret: So what's the easy way to print a whole float? If I can't
trust print to do it because print is rounding? I can't printf 'cause
I don't know where the float actually ends?
dferret: "whole float" as in to whatever precision $j is actually
living in memory.
cfedde: remember that even double floats are approximations of
the actual value with some posible error.
dferret: Sure. I understand. In the case above I would expect
print to print
"13.999999999999999999132638262011596452794037759304046630859375". If
I wanted it rounded I'd printf it myself. You said print rounds by
default -- is there a way to disable that?
cfedde: nope
whorian: hi
*** yoo (~momo@200.86.20.13) has joined channel #perl
*** Mode change "+v yoo" on #perl by Roderick
dferret: weird.
cfedde: and the the authors of perl are probably smarter than you
about were the error begins.
dferret: I'm sure they are. Listening to a Damian lecture gives me
a headache due to excessive brilliance. -grin- *** yoo has left
channel #perl
cfedde: the number of decemal places that print uses is usualy
too many for most practical purposes anyway.
cfedde: perldoc perlnumber
dngor: EYE-NUMBINGLY BRIGHT
whorian: WHAT
dferret: The lesson I learned tonight is: Just because print spits
out a round number doesn't mean that your scalar has a round number
in it. It may be rounded. I didn't know that. I thought print would
always print all the precision in memory. cfedde: usualy when you
are working with floating point numbers you want to see if your
result is within some error brackets.
dferret: s/It may be rounded/print may be rounding your scalar for
you/
dferret: error brackets?
cfedde: s/ may be/is/
dferret: ya.
cfedde: usualy you want to test that your result is within say
10e-3 or 10e-6 of what you expect
cfedde: digits beyond the expected accuracy are just noise.
Leolo: there's a var that controls print's precision, iirc
dferret: Ya, but I don't know what I'm expecting, I'm just
expecting something rediculously close to an integer, so I'll just
use sprintf("%.0f", $j) to force it into an int for me... I didn't
know I had to be paranoid in that way. cfedde: Leolo: we found
$#. but it appears to be depreciated.
Leolo: $# The output format for printed numbers.
Leolo: right
dferret grins
Leolo: dferret : why not use int() to force it into an int?
cfedde: dferret: you need to decide what "rediculously close"
means in your context.
cfedde: Leolo: read the backlog
dferret laughs
dferret: I could paste the backlog into channel? -mischevious grin-
Leolo: the back-log can't be nearly as boring as the proposal
I'm writting
dferret: I hope it's a bikeshed. I like bikesheds.