Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Ben Bacarisse Newsgroups: comp.lang.c Subject: Re: on an analogy for verifying whether another digit fits (into an unsigned type) Date: Sat, 29 Jan 2022 02:36:38 +0000 Organization: A noiseless patient Spider Lines: 46 Message-ID: <87k0ejxo7d.fsf@bsb.me.uk> References: <86mtjws9cg.fsf@levado.to> <86k0eyplyy.fsf@levado.to> <87a6fu5l2q.fsf@bsb.me.uk> <86wnij8hq6.fsf@levado.to> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: reader02.eternal-september.org; posting-host="00be0330ed62b735868e93f7a4aba188"; logging-data="26812"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+93ipoRBANeI/RXZBMZpIXhqiCGvvDprA=" Cancel-Lock: sha1:wM9+yKejw/Gfx3xSurbd0W8XKhA= sha1:an4yEB3NmT8YMDhe5RZKbQii+Bc= X-BSB-Auth: 1.7b514e1dc20125932537.20220129023638GMT.87k0ejxo7d.fsf@bsb.me.uk Xref: csiph.com comp.lang.c:164707 Meredith Montgomery writes: > Ben Bacarisse writes: > >> Meredith Montgomery writes: >> >>> Bart writes: >>> >>>> On 16/01/2022 02:27, Meredith Montgomery wrote: >>>>> uint64_t array_to_uint64(char *s, uint64_t *u) >>>>> { >>>>> uint64_t pos; >>>>> uint64_t r; >>>>> uint64_t c; >>>>> pos = 0; r = 0; >>>>> for ( ;; ) { >>>>> c = (uint64_t) (unsigned char) (s[pos] - '0'); >>>>> if (c < 10) { >>>>> if( ((UINT64_MAX - c) / 10) >= r) >>>> >>>> Dividing by 10 each time is unnecessary (even if usually optimised to >>>> shifts and multiplies). >>>> >>>> You only need to make this check after you've already processed 19 >>>> characters, as it could overflow on the 20th, but not before. >>>> >>>> I think when pos >= 18. >>> >>> I suppose you're right, but imagine putting such check there. It would >>> take even more paragraphs to explain it to myself some time later when >>> I'm trying to figure out what I wrote a while back. >> >> You could just check that the array contains a string of digits >> lexicographically less than or equal to 18446744073709551615. If there >> are fewer digits than this, or, at every position, the digit you have is >> no greater than the corresponding digit of that number, you are ok. > > That seems correct, but if I change the size of my register, then I must > replace the number too. :-) Sure. Just as you'd have to replace UINT64_MAX and so on. Remember you don't have to write 18446744073709551615. You could use snprintf to put UINT64_MAX into a static buffer. -- Ben.