improve range check

master
leitner 22 years ago
parent 674a60b278
commit 7f3c1ccc0c

@ -5,9 +5,13 @@ unsigned int scan_ulong(const char* src,unsigned long int* dest) {
register unsigned long int l=0; register unsigned long int l=0;
register unsigned char c; register unsigned char c;
while ((c=*tmp-'0')<10) { while ((c=*tmp-'0')<10) {
unsigned long int m=l; unsigned long int n;
l=l*10+c; /* division is very slow on most architectures */
if ((l>>3) < m) break; n=l<<3; if ((n>>3)!=l) break;
if (n+(l<<1) < n) break;
n+=l<<1;
if (n+c < n) break;
l=n+c;
++tmp; ++tmp;
} }
*dest=l; *dest=l;

@ -5,9 +5,13 @@ unsigned int scan_ulonglong(const char *src,unsigned long long *dest) {
register unsigned long long l=0; register unsigned long long l=0;
register unsigned char c; register unsigned char c;
while ((c=*tmp-'0')<10) { while ((c=*tmp-'0')<10) {
unsigned long long m=l; unsigned long long n;
l=l*10+c; /* division is very slow on most architectures */
if ((l>>3) < m) break; n=l<<3; if ((n>>3)!=l) break;
if (n+(l<<1) < n) break;
n+=l<<1;
if (n+c < n) break;
l=n+c;
++tmp; ++tmp;
} }
*dest=l; *dest=l;

@ -0,0 +1,16 @@
#include <assert.h>
#include <limits.h>
#include "scan.h"
int main() {
unsigned long l;
char buf[100];
assert(scan_ulong("12345",&l)==5 && l==12345);
assert(scan_ulong("-12345",&l)==0);
assert(scan_ulong("4294967295",&l)==10 && l==4294967295ul);
if (sizeof(unsigned long)==4) {
assert(scan_ulong("4294967296",&l)==9 && l==429496729);
assert(scan_ulong("42949672950",&l)==10 && l==4294967295ul);
assert(scan_ulong("5294967295",&l)==9 && l==529496729);
}
}
Loading…
Cancel
Save