I wrote a program to calculate the range of unsigned integers one could get from a certain number of bits (from 1 to 32).
(Actually, it was a problem I found in KDevelop, and the original solution was supposed to be writ up in C. I thought I'd try my hand at doing it in Perl. The problem read:
So i wrote this program:
#!/usr/bin/perl -l #Program to calculate the range of unsigned integer numbers #produced from 1 to 32 bits. use warnings; use strict; for(0..32){ my $bin='0b'.'1'x$_; print "$_ : 0 to ",oct $bin; }
and it worked great. But then I tried the C solution provided with KDevelop:
#include <stdio.h> #include <stdlib.h> main () { long int i=1,j=i; /* title */ puts("Bits\tRange"); puts("----\t-----"); /* O/P data and calc the next * set of values */ for (i=1; i<=32; i++) { printf("%2ld\t0-%12lu\n", i, j*=2); } }
but it printed 0-0 as the range for 64 bits. I'm guessing there was a buffer overflow at 64 bits (?). (btw, for the pedantic, the program doesn't work correctly, and you must change j*=2 to (j*=2)-1 for it to).
So i changed the for loop in my script above to:
for(31..64){
to see if Perl would be so affected. It worked OK! But it produced a slew of error messages claiming:
Binary number > 0b11111111111111111111111111111111 non-portable at ./b +its line 11
So I included a use diagnostics at the top of my code, adn got a helpful error message, explaining everything:
Integer overflow in binary number at ./bits line 12 (#1) (W overflow) The hexadecimal, octal or binary number you have spec +ified either as a literal or as an argument to hex() or oct() is too big + for your architecture, and has been converted to a floating point numb +er. On a 32-bit architecture the largest hexadecimal, octal or binary +number representable without overflow is 0xFFFFFFFF, 037777777777, or 0b11111111111111111111111111111111 respectively. Note that Perl transparently promotes all numbers to a floating point representat +ion internally--subject to loss of precision errors in subsequent operations.
And, a bit down the line:
Binary number > 0b11111111111111111111111111111111 non-portable at ./b +its line 12 (#2) (W portable) The binary number you specified is larger than 2**32- +1 (4294967295) and therefore non-portable between systems. See perlport for more on portability concerns.
That cleared up why the error messages were coming up.
So, a few questions:
Thanks
janitored by ybiC: Retitle from "Buffer overflow: Perl vs C" as per consideration process, add balanced <readmore> tags
In reply to Integer overflow in Perl and C by amrangaye
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |