improve range check
This commit is contained in:
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;
|
||||||
|
16
test/scan.c
Normal file
16
test/scan.c
Normal file
@ -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…
x
Reference in New Issue
Block a user