I read a book on C, there is such an example and a test task for it:

void itoa(int n, char s[]) { int i, sign; if ((sign = n) < 0) /* record sign */ n = -n; /* make n positive */ i = 0; do { /* generate digits in reverse order */ s[i++] = n % 10 + '0'; /* get next digit */ } while ((n /= 10) > 0); /* delete it */ if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s); } 

3-4. bla-bla-bla ... itoa will not be able to handle the largest negative number equal to
-(2^wordsize-1) . Explain why this is happening.

I'm still very tight with the presentation of the processes actually taking place. Such a number cannot be processed, because (roughly speaking) there is no corresponding positive for it and INT_MAX (or analog, if done for some long) is one less than what should be the result of n = -n ? If so, what at this moment is written into the variable n? 0x0 ... 01? 0xF0 ... 0? Just INT_MAX? Will it depend on the particular machine?

  • Noodles on the soup. It will not be able to process - (2 ^ wordsize) (for double-byte integers), and - (2 ^ wordsize-1) - please. Since INT_MAX will be just 2 ^ wordsize-1 (but all this is for 16-bit platforms, if wordsize == 16) - alexlz

1 answer 1

@alexlz , here is no noodle ...

Check:

  if (INT_MIN == -INT_MIN) puts("xaxa"); 

(in gcc when compiling warning about overflow).

And then immediately fall out of the do ... while() , since the quotient will be negative.

-

The function is easily corrected by checking for INT_MIN after if ((sign = n) < 0) . In this case, the first digit (and the first division by 10) is calculated using unsigned

  ... i = 0; if (n == INT_MIN) { // лучше с константами. Компилятор может просто все подставить s[i++] = (unsigned)INT_MIN % 10 + '0'; n = (unsigned)INT_MIN / 10; } 

Next, leave everything.

-

@Fike , yes this is due to overflow (i.e. there is no positive for it).

UPDATE

It’s probably better to replace the whole itoa()

  int i = 0, sign; if ((sign = n) < 0) /* record sign */ if (n == INT_MIN) { s[i++] = (unsigned)INT_MIN % 10 + '0'; n = (unsigned)INT_MIN / 10; } else n = -n; /* make n positive */ do { ... 
  • @avp int main () {int n = 0x80000001; char s [20]; itoa (n, s); printf ("% s \ n", s); return 0; } alex @ ubuntu: ~ / tmp $ ./a.out -2147483647 With int n = 0x80000000; we get the promised bummer Perhaps I should have focused on the fact that INT_MIN is not - (2 ^ wordsize-1), but - (2 ^ wordsize) - alexlz
  • one
    Little-little lied, but with the filing of the vehicle. INT_MIN = - (2 ^ (n-1)) (for 16bit - - (2: (wordsize-1))). He didn’t set the bracket, but I didn’t notice - alexlz