Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #59213 > unrolled thread

code for 32/64 bit strtoul strtol strtoull strtoll

Started byjacob navia <jacob@jacob.remcomp.fr>
First post2015-03-29 17:33 +0200
Last post2015-04-01 15:55 +0000
Articles 20 on this page of 72 — 15 participants

Back to article view | Back to comp.lang.c


Contents

  code for 32/64 bit strtoul strtol strtoull strtoll jacob navia <jacob@jacob.remcomp.fr> - 2015-03-29 17:33 +0200
    code for 32/64 bit strtoul strtol strtoull strtoll asetofsymbols@gmail.com - 2015-03-29 09:22 -0700
      Re: code for 32/64 bit strtoul strtol strtoull strtoll Barry Schwarz <schwarzb@dqel.com> - 2015-03-29 15:12 -0700
        Re: code for 32/64 bit strtoul strtol strtoull strtoll asetofsymbols@gmail.com - 2015-03-29 23:07 -0700
    Re: code for 32/64 bit strtoul strtol strtoull strtoll Barry Schwarz <schwarzb@dqel.com> - 2015-03-29 09:44 -0700
      Re: code for 32/64 bit strtoul strtol strtoull strtoll jacob navia <jacob@jacob.remcomp.fr> - 2015-03-29 19:05 +0200
        Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-29 12:15 -0700
    Re: code for 32/64 bit strtoul strtol strtoull strtoll Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-03-30 02:01 +0100
      Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-29 19:48 -0700
        Re: code for 32/64 bit strtoul strtol strtoull strtoll Barry Schwarz <schwarzb@dqel.com> - 2015-03-29 22:08 -0700
          Re: code for 32/64 bit strtoul strtol strtoull strtoll Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-03-30 12:44 +0100
            Re: code for 32/64 bit strtoul strtol strtoull strtoll Barry Schwarz <schwarzb@dqel.com> - 2015-03-30 09:04 -0700
              Re: code for 32/64 bit strtoul strtol strtoull strtoll Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-03-30 21:00 +0100
          Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-30 08:24 -0700
        Re: code for 32/64 bit strtoul strtol strtoull strtoll Tim Rentsch <txr@alumni.caltech.edu> - 2015-03-30 07:21 -0700
    Re: code for 32/64 bit strtoul strtol strtoull strtoll Ian Collins <ian-news@hotmail.com> - 2015-03-30 18:02 +1300
      Re: code for 32/64 bit strtoul strtol strtoull strtoll Richard Heathfield <rjh@cpax.org.uk> - 2015-03-30 08:03 +0100
        Re: code for 32/64 bit strtoul strtol strtoull strtoll Ian Collins <ian-news@hotmail.com> - 2015-03-30 20:33 +1300
          Re: code for 32/64 bit strtoul strtol strtoull strtoll Ian Collins <ian-news@hotmail.com> - 2015-03-30 20:35 +1300
    Re: code for 32/64 bit strtoul strtol strtoull strtoll Tim Rentsch <txr@alumni.caltech.edu> - 2015-03-30 07:27 -0700
    Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-30 09:08 -0700
    Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-30 09:29 -0700
    Re: code for 32/64 bit strtoul strtol strtoull strtoll Robert Wessel <robertwessel2@yahoo.com> - 2015-03-30 15:16 -0500
      Re: code for 32/64 bit strtoul strtol strtoull strtoll jacob navia <jacob@jacob.remcomp.fr> - 2015-03-31 00:15 +0200
        Re: code for 32/64 bit strtoul strtol strtoull strtoll Robert Wessel <robertwessel2@yahoo.com> - 2015-03-31 01:42 -0500
      Re: code for 32/64 bit strtoul strtol strtoull strtoll Bartc <bc@freeuk.com> - 2015-03-30 23:39 +0100
        Re: code for 32/64 bit strtoul strtol strtoull strtoll Robert Wessel <robertwessel2@yahoo.com> - 2015-03-31 01:44 -0500
          Re: code for 32/64 bit strtoul strtol strtoull strtoll Bartc <bc@freeuk.com> - 2015-03-31 13:01 +0100
            Re: code for 32/64 bit strtoul strtol strtoull strtoll Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-03-31 05:13 -0700
            Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-31 08:06 -0700
              Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-31 08:26 -0700
              Re: code for 32/64 bit strtoul strtol strtoull strtoll Richard Heathfield <rjh@cpax.org.uk> - 2015-03-31 16:40 +0100
                Re: code for 32/64 bit strtoul strtol strtoull strtoll Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-03-31 09:39 -0700
                Re: code for 32/64 bit strtoul strtol strtoull strtoll Kaz Kylheku <kaz@kylheku.com> - 2015-03-31 18:22 +0000
                  Re: code for 32/64 bit strtoul strtol strtoull strtoll Richard Heathfield <rjh@cpax.org.uk> - 2015-03-31 19:36 +0100
                    Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-31 12:11 -0700
                    Re: code for 32/64 bit strtoul strtol strtoull strtoll Kaz Kylheku <kaz@kylheku.com> - 2015-03-31 19:23 +0000
              Re: code for 32/64 bit strtoul strtol strtoull strtoll Bartc <bc@freeuk.com> - 2015-03-31 16:52 +0100
                Re: code for 32/64 bit strtoul strtol strtoull strtoll glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-03-31 17:54 +0000
                  Re: code for 32/64 bit strtoul strtol strtoull strtoll raltbos@xs4all.nl (Richard Bos) - 2015-03-31 18:51 +0000
                    Re: code for 32/64 bit strtoul strtol strtoull strtoll Richard Heathfield <rjh@cpax.org.uk> - 2015-03-31 20:05 +0100
                      Re: code for 32/64 bit strtoul strtol strtoull strtoll James Kuyper <jameskuyper@verizon.net> - 2015-03-31 15:18 -0400
                        Re: code for 32/64 bit strtoul strtol strtoull strtoll Richard Heathfield <rjh@cpax.org.uk> - 2015-03-31 20:49 +0100
                          Re: code for 32/64 bit strtoul strtol strtoull strtoll Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-03-31 13:06 -0700
                          Re: code for 32/64 bit strtoul strtol strtoull strtoll raltbos@xs4all.nl (Richard Bos) - 2015-04-06 13:03 +0000
                            Re: code for 32/64 bit strtoul strtol strtoull strtoll Bartc <bc@freeuk.com> - 2015-04-06 14:27 +0100
                            Re: code for 32/64 bit strtoul strtol strtoull strtoll Richard Heathfield <rjh@cpax.org.uk> - 2015-04-06 17:01 +0100
                              Re: code for 32/64 bit strtoul strtol strtoull strtoll Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-04-06 11:25 -0700
                              Re: code for 32/64 bit strtoul strtol strtoull strtoll James Kuyper <jameskuyper@verizon.net> - 2015-04-06 23:34 -0400
                                Re: code for 32/64 bit strtoul strtol strtoull strtoll glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-04-07 03:46 +0000
                                  Re: code for 32/64 bit strtoul strtol strtoull strtoll James Kuyper <jameskuyper@verizon.net> - 2015-04-08 11:05 -0400
                                    Re: code for 32/64 bit strtoul strtol strtoull strtoll Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-04-08 08:31 -0700
                        Re: code for 32/64 bit strtoul strtol strtoull strtoll glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-03-31 19:54 +0000
                          Re: code for 32/64 bit strtoul strtol strtoull strtoll James Kuyper <jameskuyper@verizon.net> - 2015-03-31 16:55 -0400
                            Re: code for 32/64 bit strtoul strtol strtoull strtoll Bartc <bc@freeuk.com> - 2015-03-31 22:20 +0100
                            Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-31 14:36 -0700
                            Re: code for 32/64 bit strtoul strtol strtoull strtoll Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-03-31 14:55 -0700
                              Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-03-31 17:00 -0700
                                Re: code for 32/64 bit strtoul strtol strtoull strtoll Bartc <bc@freeuk.com> - 2015-04-01 01:24 +0100
                                Re: code for 32/64 bit strtoul strtol strtoull strtoll James Kuyper <jameskuyper@verizon.net> - 2015-03-31 23:33 -0400
                                  Re: code for 32/64 bit strtoul strtol strtoull strtoll Richard Heathfield <rjh@cpax.org.uk> - 2015-04-01 04:42 +0100
                  Re: code for 32/64 bit strtoul strtol strtoull strtoll Bartc <bc@freeuk.com> - 2015-03-31 20:26 +0100
              Re: code for 32/64 bit strtoul strtol strtoull strtoll Ian Collins <ian-news@hotmail.com> - 2015-04-01 10:33 +1300
                Re: code for 32/64 bit strtoul strtol strtoull strtoll Robert Wessel <robertwessel2@yahoo.com> - 2015-04-01 04:33 -0500
                  Re: code for 32/64 bit strtoul strtol strtoull strtoll Bartc <bc@freeuk.com> - 2015-04-01 12:43 +0100
                    Re: code for 32/64 bit strtoul strtol strtoull strtoll Robert Wessel <robertwessel2@yahoo.com> - 2015-04-02 01:02 -0500
                      Re: code for 32/64 bit strtoul strtol strtoull strtoll asetofsymbols@gmail.com - 2015-04-01 23:57 -0700
                        Re: code for 32/64 bit strtoul strtol strtoull strtoll Robert Wessel <robertwessel2@yahoo.com> - 2015-04-03 00:29 -0500
                      Re: code for 32/64 bit strtoul strtol strtoull strtoll Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-04-02 09:01 -0700
                        Re: code for 32/64 bit strtoul strtol strtoull strtoll Keith Thompson <kst-u@mib.org> - 2015-04-02 14:30 -0700
                        Re: code for 32/64 bit strtoul strtol strtoull strtoll Robert Wessel <robertwessel2@yahoo.com> - 2015-04-03 00:39 -0500
                  Re: code for 32/64 bit strtoul strtol strtoull strtoll glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-04-01 15:55 +0000

Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#59287

FromKeith Thompson <kst-u@mib.org>
Date2015-03-30 09:08 -0700
Message-ID<87zj6ujwn7.fsf@kst-u.example.com>
In reply to#59213
jacob navia <jacob@jacob.remcomp.fr> writes:
> Here is the code for the above functions.
[...]
> #define SIGNED32    1
> #define UNSIGNED32  2
> #define SIGNED64    4
> #define UNSIGNED64  8
> #define OVERFLOW_FLAG   -1

Your macro names imply that long is 32 bits and long long is 64 bits.
This is not guaranteed -- and the code doesn't actually depend on it.
Changing the macro names (to, say, LONG, UNSIGNED_LONG, LONG_LONG, and
UNSIGNED_LONG_LONG) would improve clarity.

[...]

> #ifdef TEST
[...]
> int main(int argc,char *argv[])
[...]
>     int base = 0;
[...]
>     if (argc > 2)
>         base = atoi(argv[2]);
[...]
>     unsigned long long m = Strtoull(s,&end,0);

You set base (with a default value of 0), but you never use it.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#59290

FromKeith Thompson <kst-u@mib.org>
Date2015-03-30 09:29 -0700
Message-ID<87r3s6jvop.fsf@kst-u.example.com>
In reply to#59213
jacob navia <jacob@jacob.remcomp.fr> writes:
[...]
>         if((c >= '0') && (c <= nbmax)) {
>             digit = c - '0';
>         }
>         else if ((c >= 'a') && (c <= cbmax)) {
>             digit = (c - 'a') + 10;
>         }
>         else if ( (c >= 'A') && (c <= (char)toupper(cbmax))) {
>             digit = (c - 'A') + 10;
>         }
>         else { /* invalid char. Stop. */
>             break;
>         }
[...]

This assumes that the uppercase and lowercase letters have contiguous
encodings -- true for ASCII and derivatives, false for EBCDIC.

If you intend to write implementations that are 100% portable C,
I suggest using a lookup table.

If the code is intended to be used in an implementation of
the C runtime library, and you're able to assume contiguous
representations, non-portable code is perfectly acceptable (but it
would require a little extra work if the code were ever ported to an
EBCDIC-based system).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#59307

FromRobert Wessel <robertwessel2@yahoo.com>
Date2015-03-30 15:16 -0500
Message-ID<pcbjhade8kuntaatb4fgsfa9s0r3s9nj66@4ax.com>
In reply to#59213
On Sun, 29 Mar 2015 17:33:27 +0200, jacob navia
<jacob@jacob.remcomp.fr> wrote:

>Hi
>
>Here is the code for the above functions.
>
>1: A single function will perform all 4 conventions.
>
>2: I have incorporated the suggestions of Mr Wessel and eliminated all 
>tables/floating point calculations for getting the maximum number of 
>digits.
>
>3: I test for overflow at each stage. For the version presented here I 
>stay within C99 and I am not using the _overflow() function of lcc-win 
>that returns the value of the overflow flag.
>
>4: I added at the end two small pieces of code to test it with an input 
>string that is passed through the argc/argv mechanism, or to test the 
>speed of the software passing a number of iterations and a number to 
>convert. Two #defines select them: TEST and SPEED respectively. By 
>default there are no defines and the software needs a main function to 
>get an executable
>
>5: To avoid conflicts with the standard library of the compiler you are 
>using I have written all visible function names with upper case "S"
>
>/*------------------------------------------------------------------
>  * strtoul() - Conversion of a string of base n to an unsigned long
>/*----------------------------------------------------------------*/
>#include <ctype.h>
>#include <errno.h>
>#include <limits.h>
>#include <stdlib.h>
>
>#define SIGNED32    1
>#define UNSIGNED32  2
>#define SIGNED64    4
>#define UNSIGNED64  8
>#define OVERFLOW_FLAG   -1
>
>static unsigned long long _Strtoull(const char *input,
>                      char **endptr, int base, int Flags)
>{
>     char nbmax; // The maximum numerical digit that can be read
>     int tbase = 10; // Default base when base is zero
>     int ScanSuffix = 0; // Do we scan any suffixes?
>     int ReadSomething=0; // Did we read something in?
>     char sign = 0;   // If negative sign is '-'
>     char cbmax = 0;  // Max digit that can be read for base > 10
>     int digit = 0;  // Digit  read. Reused as overflow flag.
>     int c;      // Character just read.
>     unsigned long long temp;
>     unsigned long long maxval; // Max value that doesn't overflow
>     unsigned long long errval; /* Error return */
>     unsigned long long value = 0; /* The number we are scanning */
>
>     /* Store input into endptr immediately to save its value
>       since we are going to reuse it */
>     if (endptr) *endptr = input;
>
>     /* The value of the "base" argument should be zero or
>       2 <= base <= 36.  What happens with negative values of "base"
>       or with base 1? The standard is silent about that.
>       We just do not accept any other values for "base" besides
>       those explicitely allowed.  Is it better to crash later
>       when dereferencing a NULL pointer? Or to give just an
>       error now? */
>     if (base < 0 || base == 1 || base > 36 || input == NULL) {
>         errno = ERANGE;
>         return 0;
>     }
>
>     /* C99: 7.20.1.4.2
>       First, they decompose the input string into three parts:
>     * an initial, possibly empty, sequence of white-space
>     * characters  (as specified by the isspace function),
>     */
>     while (isspace(*input)) { input++; }
>
>     if((*input == '-') || (*input == '+')) {
>         sign = *input;
>         input++;
>     }
>
>     /* C99: 7.20.1.4.5:
>     If the subject sequence has the expected form and the value
>     of base is zero, the sequence of characters starting with the
>     first digit is interpreted as an integer constant according
>     to the rules of 6.4.4.1.
>     C99: 7.20.1.4.3:
>     If the value of base is 16, the characters 0x or 0X may
>     optionally precede the sequence of letters and digits,
>     following the sign if present.
>     */
>     if(*input == '0' && (base == 0 || base == 16)) {
>         if((input[1] == 'X') || (input[1] == 'x')) {
>             tbase = 16;
>             input+=2;
>         }
>         else if (base == 0) {
>             tbase = 8;
>             /* We have read a zero! We MUST bump "ReadSomething"
>               because if not the trivial sequence "0" wouldn't
>               be recognized!! Note that "0x" is NOT a valid
>               sequence so we haven't read anything UNTIL we
>               read a number later
>             */
>             ReadSomething=1;
>             input++;
>         }
>     }
>
>     /* C99: 7.20.1.4.7:
>     If the subject sequence is empty or does not have the
>     expected form, no conversion is performed; the value of
>     nptr is stored in the object pointed to by endptr,
>     provided that endptr is not a null pointer.
>     */
>     if (*input == 0 && ReadSomething == 0)      return 0;
>
>     /* If we set tbase above put its value into base. We
>     must save the fact that if the original base was zero
>     we should look for an eventual suffix. Put that
>     into the ScanSuffix variable. Obviously ScanSuffix
>     could be eliminated and we could set tbase to 4876 say,
>     since its value is no longer used. At the end we
>     could test if tbase is 4876. That would save 4 bytes
>     but make this more unreadable... Not worth */
>
>     if (base == 0) {
>         base = tbase;
>         ScanSuffix = 1;
>     }
>
>     if (base <= 10) {
>         nbmax = (char)((char)'0' + (char)(base - 1));
>     }
>     else {
>         nbmax = '9';
>         cbmax = (char)((char)'a' + (char)(base - 11));
>     }
>     /* Set error return / maxval according to the flags given */
>     if (Flags&SIGNED64) { /* Returning a signed 64 bit number */
>         if(sign == '-') {
>             maxval = LLONG_MAX;
>             errval = (unsigned long long)LLONG_MIN;
>         }
>         else maxval = errval = LLONG_MAX;
>     }
>     else if (Flags&UNSIGNED64) { /* Returning a 64 bit unsigned */
>         errval = maxval = ~0ULL;
>     }
>     else if (Flags &SIGNED32) {
>         errval = maxval = LONG_MAX;
>     }
>     else { /* Must be UNSIGNED32 */
>         errval = maxval = ULONG_MAX;
>     }
>     while (*input == '0') input++; /* Ignore leading zeroes */
>     /* Preliminary work is ended. Start converting the number */
>     while ( (c=*input) != 0) {
>         if((c >= '0') && (c <= nbmax)) {
>             digit = c - '0';
>         }
>         else if ((c >= 'a') && (c <= cbmax)) {
>             digit = (c - 'a') + 10;
>         }
>         else if ( (c >= 'A') && (c <= (char)toupper(cbmax))) {
>             digit = (c - 'A') + 10;
>         }
>         else { /* invalid char. Stop. */
>             break;
>         }
>         temp = (value* (unsigned long)base);
>         /* Test for overflow in the multiplication above */
>         if (temp < value) {
>             digit = OVERFLOW_FLAG;
>             break;
>         }
>         temp += digit;
>         // Test for overflow again
>         if (temp < value) {
>             digit = OVERFLOW_FLAG;
>             break;
>         }
>         value = temp;
>         input++;
>         ReadSomething++;
>     }
>     if (c != 0 && digit == OVERFLOW_FLAG) {
>         /* Ignore all excess digits */
>         while (((*input >= '0') && (*input <= nbmax)) ||
>             ((*input >= 'a') && (*input <= cbmax)) ||
>             ((*input >= 'A') && (*input <= (char)toupper(cbmax)))) {
>             input++;
>         }
>     }
>     if (endptr && ReadSomething && ScanSuffix) {
>         /* Accept U,L, UL, ULL suffixes.
>           All other suffixes are ignored */
>         if (*input == 'u' || *input == 'U') input++;
>         if (*input == 'l' || *input == 'L') input ++;
>         if ((Flags&(SIGNED64|UNSIGNED64)) &&
>               (*input == 'l' || *input == 'L')) input++;
>     }
>     if (endptr != NULL && ReadSomething > 0) {
>         *endptr = input;
>     }
>     if (value > maxval || digit == OVERFLOW_FLAG) {
>         errno = ERANGE;
>         value = errval;
>     }
>     else if (sign ==  '-') {
>         if (Flags&(SIGNED32|UNSIGNED32))
>             value = -(long long)(value&0xffffffff);
>         else
>             value = -(long long)value;
>     }
>     return(value);
>}
>
>/*-------------------------------------------------------------*/
>/* strtol() - string of base n to an unsigned long integer     */
>/*-------------------------------------------------------------*/
>unsigned long Strtol(const char *input, char **endptr, int base)
>{
>     return(_Strtoull(input, endptr, base, SIGNED32));
>}
>
>/*------------------------------------------------------------*/
>/* strtol() - string of base n to an unsigned long integer    */
>/*------------------------------------------------------------*/
>long Strtoul(const char *input, char **endptr, int base)
>{
>     return(_Strtoull(input, endptr, base, UNSIGNED32));
>}
>
>/*------------------------------------------------------------*/
>/* strtoull() String base n to an unsigned long long r        */
>/*------------------------------------------------------------*/
>unsigned long long Strtoull(const char *input, char **endptr, int base)
>{
>     return(_Strtoull(input, endptr, base, UNSIGNED64));
>}
>
>/*-----------------------------------------------------------*/
>/* strtoll() String of base n to a signed long long          */
>/*-----------------------------------------------------------*/
>long long Strtoll(const char *input, char **endptr, int base)
>{
>     return(_Strtoull(input, endptr, base, SIGNED64));
>}
>
>#ifdef TEST
>// process the argv[1] and write results */
>#include <stdio.h>
>#include <math.h>
>#include <string.h>
>int main(int argc,char *argv[])
>{
>     char *end;
>     char *s = "-2147483647";
>     int save_errno;
>     int base = 0;
>     if (argc > 1)
>         s = argv[1];
>     else {
>         fprintf(stderr,"Usage: %s <number> [base]\n",argv[0]);
>         return EXIT_FAILURE;
>     }
>     if (argc > 2)
>         base = atoi(argv[2]);
>     errno = 0;
>     unsigned long long m = Strtoull(s,&end,0);
>     save_errno = errno;
>     printf("strtoull(%s):\n         %llu %lld",argv[1],m,end-s);
>     printf(" errno = %s\n",strerror(save_errno));
>     errno = 0;
>     m = Strtoll(s,&end,0);
>     save_errno=errno;
>     printf("strtoll(%s):\n        %llu %lld",argv[1],m,end-s);
>     printf(" errno = %s\n",strerror(save_errno));
>}
>#endif
>#ifdef SPEED
>// argv[1] is number of iterations, argv[2] is value */
>#include <stdio.h>
>int main(int argc,char *argv[])
>{
>     int i;
>     char *s = "-123456789";
>     if (argc > 1)
>         i = atoi(argv[1]);
>     else {
>         fprintf(stderr,"Usage: %s <iterations> <number>\n",argv[0]);
>         return EXIT_FAILURE;
>     }
>     if (argc > 2)
>         s = argv[2];
>     while (i > 0) {
>         Strtoll(s,NULL,10);
>         i--;
>     }
>}
>#endif


Your character to numeric conversions are assuming that the letters
are contiguous.  That's true for ASCII, not for some other encodings,
like EBCDIC.

I'm pretty sure you can't simplify the multiplication overflow test
like that.  The check for the sum being less than either of the
addends works for addition, but it doesn't for multiplication, some
special cases excepted (obviously a multiplication by two could be
tested that way).  Consider a 16 bit example:  (32769*35)%65536 is
32803.

[toc] | [prev] | [next] | [standalone]


#59312

Fromjacob navia <jacob@jacob.remcomp.fr>
Date2015-03-31 00:15 +0200
Message-ID<mfchuk$goc$1@speranza.aioe.org>
In reply to#59307
Le 30/03/2015 22:16, Robert Wessel a écrit :
> I'm pretty sure you can't simplify the multiplication overflow test
> like that.  The check for the sum being less than either of the
> addends works for addition, but it doesn't for multiplication, some
> special cases excepted (obviously a multiplication by two could be
> tested that way).  Consider a 16 bit example:  (32769*35)%65536 is
> 32803.

Yes, and Mr Heathfield proved that... and others!

blush!

:-(

OK, now I will do

maxvalNotOverflow = maxval/base;

and then, at each step:

	if (value > maxvalNotOverflow) {
		digit = OVERFLOW_FLAG;
		break;
	}
	else value = value * base;

Now, I DO believe that my test is OK when testing for an ADDITION overflow.

	if (value+digit < value) {
		digit = OVERFLOW_FLAG;
		break;
	}
	else value += digit;

OK?

[toc] | [prev] | [next] | [standalone]


#59329

FromRobert Wessel <robertwessel2@yahoo.com>
Date2015-03-31 01:42 -0500
Message-ID<ohfkhal090un59pqp14eao3ku615ramb0o@4ax.com>
In reply to#59312
On Tue, 31 Mar 2015 00:15:47 +0200, jacob navia
<jacob@jacob.remcomp.fr> wrote:

>Le 30/03/2015 22:16, Robert Wessel a écrit :
>> I'm pretty sure you can't simplify the multiplication overflow test
>> like that.  The check for the sum being less than either of the
>> addends works for addition, but it doesn't for multiplication, some
>> special cases excepted (obviously a multiplication by two could be
>> tested that way).  Consider a 16 bit example:  (32769*35)%65536 is
>> 32803.
>
>Yes, and Mr Heathfield proved that... and others!
>
>blush!
>
>:-(
>
>OK, now I will do
>
>maxvalNotOverflow = maxval/base;
>
>and then, at each step:
>
>	if (value > maxvalNotOverflow) {
>		digit = OVERFLOW_FLAG;
>		break;
>	}
>	else value = value * base;



I was originally thinking that the truncation computing the test value
might lead to a pessimistic value for what could overflow, but on
further reflection that's not actually true.  So the above looks good
to me.


>Now, I DO believe that my test is OK when testing for an ADDITION overflow.
>
>	if (value+digit < value) {
>		digit = OVERFLOW_FLAG;
>		break;
>	}
>	else value += digit;
>
>OK?


Yes.  Although it might be faster to do:

	value += digit;
	if (value < digit) {
		digit = OVERFLOW_FLAG;
		break;
	}


That brings up another question: what's the required behavior of the
second parameter of the strto*() functions in the case of an overflow?
My reading of the standard is that despite the overflow, the value may
well be of the "expected form", so you really need to continue reading
it, so you can set the returned pointer to the correct end-of-input
location.

[toc] | [prev] | [next] | [standalone]


#59313

FromBartc <bc@freeuk.com>
Date2015-03-30 23:39 +0100
Message-ID<mfcj93$fle$1@dont-email.me>
In reply to#59307
On 30/03/2015 21:16, Robert Wessel wrote:

> I'm pretty sure you can't simplify the multiplication overflow test
> like that.  The check for the sum being less than either of the
> addends works for addition, but it doesn't for multiplication, some
> special cases excepted (obviously a multiplication by two could be
> tested that way).  Consider a 16 bit example:  (32769*35)%65536 is
> 32803.

Isn't the multiplication only going to be by 2, 8, 10 or 16 in this case?

In the case of 10, and with a largest value of 18446744073709551615, 
then A*10 shouldn't overflow provided A is 1844674407370955161 or less.

-- 
Bartc


[toc] | [prev] | [next] | [standalone]


#59330

FromRobert Wessel <robertwessel2@yahoo.com>
Date2015-03-31 01:44 -0500
Message-ID<afgkhad77likbtrl59abp4gicrighrb2e9@4ax.com>
In reply to#59313
On Mon, 30 Mar 2015 23:39:19 +0100, Bartc <bc@freeuk.com> wrote:

>On 30/03/2015 21:16, Robert Wessel wrote:
>
>> I'm pretty sure you can't simplify the multiplication overflow test
>> like that.  The check for the sum being less than either of the
>> addends works for addition, but it doesn't for multiplication, some
>> special cases excepted (obviously a multiplication by two could be
>> tested that way).  Consider a 16 bit example:  (32769*35)%65536 is
>> 32803.
>
>Isn't the multiplication only going to be by 2, 8, 10 or 16 in this case?
>
>In the case of 10, and with a largest value of 18446744073709551615, 
>then A*10 shouldn't overflow provided A is 1844674407370955161 or less.


The base may be any (integer) value 2..36.

[toc] | [prev] | [next] | [standalone]


#59336

FromBartc <bc@freeuk.com>
Date2015-03-31 13:01 +0100
Message-ID<mfe28k$ks4$1@dont-email.me>
In reply to#59330
On 31/03/2015 07:44, Robert Wessel wrote:
> On Mon, 30 Mar 2015 23:39:19 +0100, Bartc <bc@freeuk.com> wrote:
>
>> On 30/03/2015 21:16, Robert Wessel wrote:
>>
>>> I'm pretty sure you can't simplify the multiplication overflow test
>>> like that.  The check for the sum being less than either of the
>>> addends works for addition, but it doesn't for multiplication, some
>>> special cases excepted (obviously a multiplication by two could be
>>> tested that way).  Consider a 16 bit example:  (32769*35)%65536 is
>>> 32803.
>>
>> Isn't the multiplication only going to be by 2, 8, 10 or 16 in this case?
>>
>> In the case of 10, and with a largest value of 18446744073709551615,
>> then A*10 shouldn't overflow provided A is 1844674407370955161 or less.
>
>
> The base may be any (integer) value 2..36.

Sounds like ridiculous over-specification to me, because if you're going 
to allow base 36, why not 136? Bases in the range 2 to 16 are very 
common and useful; above 16 aren't.

But anyway, whatever the base, you set up 18446744073709551615/base (or 
whatever) as the limit to check A against just before you do A*base.

(And by remembering the last base and limit, you can avoid avoid doing 
this divide on each call if this is going to cause a problem, or just 
have a table containing the limits for each base.)

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#59337

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-03-31 05:13 -0700
Message-ID<ea14473a-e3b6-40f0-9430-77c08704081a@googlegroups.com>
In reply to#59336
On Tuesday, March 31, 2015 at 1:01:24 PM UTC+1, Bart wrote:
>
> Sounds like ridiculous over-specification to me, because if you're going 
> to allow base 36, why not 136? Bases in the range 2 to 16 are very 
> common and useful; above 16 aren't.
> 
You need base 2, base 10, and base 16. Octal needs to be supported for legacy
reasons but is undesirable as octal numbers look too much like decimal numbers,
and because the digits won't fit into an 8 bit byte.
The other interesting base is base Phi. 

[toc] | [prev] | [next] | [standalone]


#59342

FromKeith Thompson <kst-u@mib.org>
Date2015-03-31 08:06 -0700
Message-ID<877ftxjjfr.fsf@kst-u.example.com>
In reply to#59336
Bartc <bc@freeuk.com> writes:
> On 31/03/2015 07:44, Robert Wessel wrote:
[...]
>> The base may be any (integer) value 2..36.
>
> Sounds like ridiculous over-specification to me, because if you're
> going to allow base 36, why not 136? Bases in the range 2 to 16 are
> very common and useful; above 16 aren't.

Base 7 is common and useful?

Bases up to 36 are permitted because the digits can be represented
straightforwardly using decimal digits and letters.  Restricting the
base to, say, 2, 8, 10, or 16 (or 0) would have been arbitrary;
permitting any base from 2 to 36 would not make the implementation
significantly easier.  (And base 36 might be an almost reasonable
way to represent numbers compactly, though it's not particularly
human-readable.)

Having said that, if the standard had restricted the value of `base`
to 0, 2, 8, 10, and 16 (and preferably defined the behavior for an
invalid base), it wouldn't have bothered me.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#59343

FromKeith Thompson <kst-u@mib.org>
Date2015-03-31 08:26 -0700
Message-ID<87384ljigv.fsf@kst-u.example.com>
In reply to#59342
Keith Thompson <kst-u@mib.org> writes:
[...]
> Bases up to 36 are permitted because the digits can be represented
> straightforwardly using decimal digits and letters.  Restricting the
> base to, say, 2, 8, 10, or 16 (or 0) would have been arbitrary;
> permitting any base from 2 to 36 would not make the implementation
> significantly easier.  (And base 36 might be an almost reasonable
> way to represent numbers compactly, though it's not particularly
> human-readable.)
[...]

I flipped the logic in that second sentence.  I meant to say that
restricting the base (rather than permitting any base from 2 to 36)
would not make the implementation significantly easier.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#59344

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-03-31 16:40 +0100
Message-ID<mfef46$89q$1@dont-email.me>
In reply to#59342
On 31/03/15 16:06, Keith Thompson wrote:
> Bartc <bc@freeuk.com> writes:
>> On 31/03/2015 07:44, Robert Wessel wrote:
> [...]
>>> The base may be any (integer) value 2..36.
>>
>> Sounds like ridiculous over-specification to me, because if you're
>> going to allow base 36, why not 136? Bases in the range 2 to 16 are
>> very common and useful; above 16 aren't.
>
> Base 7 is common and useful?

Um, yes (up to a point).

Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday.

(Admittedly its use runs out right about here.)

<snip>

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#59346

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-03-31 09:39 -0700
Message-ID<623b76d1-1022-481b-85df-14ea6d1fd18f@googlegroups.com>
In reply to#59344
On Tuesday, March 31, 2015 at 4:40:51 PM UTC+1, Richard Heathfield wrote:
> On 31/03/15 16:06, Keith Thompson wrote:
> > Bartc <bc@freeuk.com> writes:
> >> On 31/03/2015 07:44, Robert Wessel wrote:
> > [...]
> >>> The base may be any (integer) value 2..36.
> >>
> >> Sounds like ridiculous over-specification to me, because if you're
> >> going to allow base 36, why not 136? Bases in the range 2 to 16 are
> >> very common and useful; above 16 aren't.
> >
> > Base 7 is common and useful?
> 
> Um, yes (up to a point).
> 
> Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday.
> 
> (Admittedly its use runs out right about here.)
> 
Sunday is yom rishon, or the first day, in Hebrew. We think it was they who invented
the seven day week. So it's a one-based system. There's no "yom efes" or "day zero"
  

[toc] | [prev] | [next] | [standalone]


#59352

FromKaz Kylheku <kaz@kylheku.com>
Date2015-03-31 18:22 +0000
Message-ID<20150331111944.760@kylheku.com>
In reply to#59344
On 2015-03-31, Richard Heathfield <rjh@cpax.org.uk> wrote:
> On 31/03/15 16:06, Keith Thompson wrote:
>> Bartc <bc@freeuk.com> writes:
>>> On 31/03/2015 07:44, Robert Wessel wrote:
>> [...]
>>>> The base may be any (integer) value 2..36.
>>>
>>> Sounds like ridiculous over-specification to me, because if you're
>>> going to allow base 36, why not 136? Bases in the range 2 to 16 are
>>> very common and useful; above 16 aren't.
>>
>> Base 7 is common and useful?
>
> Um, yes (up to a point).
>
> Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday.
>
> (Admittedly its use runs out right about here.)

That is not "base 7", but a modulo 7 congruence.

Base 7 means we have a representation of integers based on powers
of 7. Thus we make use of 49, 343, ....

[toc] | [prev] | [next] | [standalone]


#59353

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-03-31 19:36 +0100
Message-ID<mfepdo$kei$2@dont-email.me>
In reply to#59352
On 31/03/15 19:22, Kaz Kylheku wrote:
> On 2015-03-31, Richard Heathfield <rjh@cpax.org.uk> wrote:
>> On 31/03/15 16:06, Keith Thompson wrote:
>>> Bartc <bc@freeuk.com> writes:
>>>> On 31/03/2015 07:44, Robert Wessel wrote:
>>> [...]
>>>>> The base may be any (integer) value 2..36.
>>>>
>>>> Sounds like ridiculous over-specification to me, because if you're
>>>> going to allow base 36, why not 136? Bases in the range 2 to 16 are
>>>> very common and useful; above 16 aren't.
>>>
>>> Base 7 is common and useful?
>>
>> Um, yes (up to a point).
>>
>> Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday.
>>
>> (Admittedly its use runs out right about here.)
>
> That is not "base 7", but a modulo 7 congruence.
>
> Base 7 means we have a representation of integers based on powers
> of 7. Thus we make use of 49, 343, ....

Yeah, there's a limit to how far you can stretch a joke before it snaps 
in two.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

[toc] | [prev] | [next] | [standalone]


#59356

FromKeith Thompson <kst-u@mib.org>
Date2015-03-31 12:11 -0700
Message-ID<87vbhhhthe.fsf@kst-u.example.com>
In reply to#59353
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 31/03/15 19:22, Kaz Kylheku wrote:
>> On 2015-03-31, Richard Heathfield <rjh@cpax.org.uk> wrote:
>>> On 31/03/15 16:06, Keith Thompson wrote:
>>>> Bartc <bc@freeuk.com> writes:
>>>>> On 31/03/2015 07:44, Robert Wessel wrote:
>>>> [...]
>>>>>> The base may be any (integer) value 2..36.
>>>>>
>>>>> Sounds like ridiculous over-specification to me, because if you're
>>>>> going to allow base 36, why not 136? Bases in the range 2 to 16 are
>>>>> very common and useful; above 16 aren't.
>>>>
>>>> Base 7 is common and useful?
>>>
>>> Um, yes (up to a point).
>>>
>>> Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday.
>>>
>>> (Admittedly its use runs out right about here.)
>>
>> That is not "base 7", but a modulo 7 congruence.
>>
>> Base 7 means we have a representation of integers based on powers
>> of 7. Thus we make use of 49, 343, ....
>
> Yeah, there's a limit to how far you can stretch a joke before it
> snaps in two.

Or in seven.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#59358

FromKaz Kylheku <kaz@kylheku.com>
Date2015-03-31 19:23 +0000
Message-ID<20150331122221.146@kylheku.com>
In reply to#59353
On 2015-03-31, Richard Heathfield <rjh@cpax.org.uk> wrote:
> On 31/03/15 19:22, Kaz Kylheku wrote:
>> On 2015-03-31, Richard Heathfield <rjh@cpax.org.uk> wrote:
>>> On 31/03/15 16:06, Keith Thompson wrote:
>>>> Bartc <bc@freeuk.com> writes:
>>>>> On 31/03/2015 07:44, Robert Wessel wrote:
>>>> [...]
>>>>>> The base may be any (integer) value 2..36.
>>>>>
>>>>> Sounds like ridiculous over-specification to me, because if you're
>>>>> going to allow base 36, why not 136? Bases in the range 2 to 16 are
>>>>> very common and useful; above 16 aren't.
>>>>
>>>> Base 7 is common and useful?
>>>
>>> Um, yes (up to a point).
>>>
>>> Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday.
>>>
>>> (Admittedly its use runs out right about here.)
>>
>> That is not "base 7", but a modulo 7 congruence.
>>
>> Base 7 means we have a representation of integers based on powers
>> of 7. Thus we make use of 49, 343, ....
>
> Yeah, there's a limit to how far you can stretch a joke before it snaps 
> in two.

And such a binary breakage, again, does not imply the binary number system.

[toc] | [prev] | [next] | [standalone]


#59345

FromBartc <bc@freeuk.com>
Date2015-03-31 16:52 +0100
Message-ID<mfefr3$bis$1@dont-email.me>
In reply to#59342
On 31/03/2015 16:06, Keith Thompson wrote:
> Bartc <bc@freeuk.com> writes:
>> On 31/03/2015 07:44, Robert Wessel wrote:
> [...]
>>> The base may be any (integer) value 2..36.
>>
>> Sounds like ridiculous over-specification to me, because if you're
>> going to allow base 36, why not 136? Bases in the range 2 to 16 are
>> very common and useful; above 16 aren't.
>
> Base 7 is common and useful?

I meant 2, 8, 10 and 16, which are in the range 2 to 16. Although I did 
make use of base 4 the other week (meaning I use base 4 more than base 8).

> (And base 36 might be an almost reasonable
> way to represent numbers compactly, though it's not particularly
> human-readable.)

That's a rather specialised use for which you ought be using an encoding 
like the one in base64 or Mime. You don't need support in a C library 
function (especially when C doesn't support conversion the other way to 
any base except 10 and 16).

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#59350

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2015-03-31 17:54 +0000
Message-ID<mfen05$b4f$1@speranza.aioe.org>
In reply to#59345
Bartc <bc@freeuk.com> wrote:

(snip)

> I meant 2, 8, 10 and 16, which are in the range 2 to 16. Although I did 
> make use of base 4 the other week (meaning I use base 4 more than base 8).

There is a lot of work done in base 4, if you use A, C, T, and G 
instead of 0, 1, 2, 3 for the digits.

-- glen

[toc] | [prev] | [next] | [standalone]


#59354

Fromraltbos@xs4all.nl (Richard Bos)
Date2015-03-31 18:51 +0000
Message-ID<551aec75.2399734@news.xs4all.nl>
In reply to#59350
glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:

> Bartc <bc@freeuk.com> wrote:
> 
> > I meant 2, 8, 10 and 16, which are in the range 2 to 16. Although I did 
> > make use of base 4 the other week (meaning I use base 4 more than base 8).
> 
> There is a lot of work done in base 4, if you use A, C, T, and G 
> instead of 0, 1, 2, 3 for the digits.

Well, no. Those are strings. Nobody is going to multiply your DNA with
that of another creature, except maybe David Cronenberg.

Richard

[toc] | [prev] | [next] | [standalone]


Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →

Back to top | Article view | comp.lang.c


csiph-web