[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.