14
1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

Embed Size (px)

Citation preview

Page 1: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

1

CS 162Introduction to Computer Science

Chapter 5ASCII to Integer Conversion

Herbert G. Mayer, PSUStatus 11/9/2014

Page 2: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

2

Syllabus

#include <stdio.h> for getchar() Convert Decimal Digits to int Account for Sign Check integer Overflow on 16-Bit Maxint on 32-Bit

Page 3: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

3

Specify a2i() Conversion

Reading one input char at a time, assuming the character is a decimal digit ‘0’..’9’

Convert this ASCII string of decimal digits to its corresponding integral value

For example, the incoming string “123” is converted to the integer hundred-and-twenty-three, i.e. 12310

Be aware that this input is indeed a sequence of ASCII character, not an integer value

So we have to convert the digit ‘5’ for example to the integer value 5, by subtracting from character ‘5’ the value character ‘0’, and the difference is 5

Int value of ‘5’ is: ‘5’ – ‘0’

Page 4: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

4

Implement a2i() Conversion

int a2i( void ){ // a2i int number = 0; while( ( ( c = getchar() ) >= '0' ) && ( c <= '9' ) ) {

number = number * 10 + ( c - '0' ); } //end while return number;} //end a2i

int main(){ // main

cout << “Enter a decimal number: ” << endl;cout << "The number was:” << a2i() << endl;return 0;

} //end main

Page 5: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

5

Discuss Code for a2i() Conversion

The assumption in the code is that a sequence of decimal digits can be read

However, if not a single digit is entered, the correct result of 0 is generated, due to initialization of number; see “int number = 0;”

A crucial test is: ( c = getchar() ) >= '0' ... Here a side-effect happens: A character is read from

standard in, and it is tested. Test becomes more complex, but no further input happens

The current number is shifted left by 1 decimal position (multiply by 10) and the digit value is added

Page 6: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

6

Account for Sign in a2i()

Before reading one decimal digit at a time, check for optional negative sign ‘-’ or a redundant positive sign ‘+’

Former ‘-’ will change the resulting value, by inverting the sign

State of ‘-’ has to be remembered; see variable neg

The latter ‘+’ is silently skipped

Once the sign is handled, proceed as before with the decimal digits that make the number

Page 7: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

7

Implement Sign in a2i()int is_digit( char c ){ // is_digit return ( c >= '0' ) && ( c <= '9' );} //end is_digit

int a2i0( void ){ // a2i0 int number = 0; int neg = 0; if ( c == '-' ) {

neg = 1; c = getchar();

}else if ( c == '+' ) { c = getchar();

} //end if while ( is_digit( c ) ) {

number = number * 10 + ( c - '0' );c = getchar();

} //end while return neg ? -number : number;} //end a2i0

Page 8: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

8

Discuss Sign in a2i

State variable neg is solely used to determine at the end, whether sign inversion happens

Here we us a conditional expression: return neg ? -number : number;

For the initial state of neg = 0, the decimal computed so far is returned

But if neg is set to a non-zero state, the sign is inverted, all accomplished in a single conditional expression

Note separation of the 2 options via the : and ? operators!

Page 9: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

9

Specify Overflow in a2i() on 16-Bit Delicate programming matter, analyzed by sample of

a fictitious 16-bit architecture

On 16-bit computer the largest possible integer = 32767

On a two’s-complement architecture, the largest negative value = -32768

Both cases have to be handled, without the overflow actually occurring, so we probe the growing integer value, before the next multiply by 10, MAX10 = 3276

Also track, whether scanning a negative int literal, in which case the largest next decimal digit for 3276 is 8, versus the positive literal, for which largest next decimal digit fir 3276 is 7

Page 10: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

10

Specify Overflow in a2i() on 16-Bit

Scanning a positive decimal int literal: If number scanned so far is less than 3276, which is max

32767 / 10, then scanning 1 more digit is safe, do number = number * 10 + ( c-'0’ ); But if number scanned so far is in critical range 3276, then

only some digits are safe, namely ‘0’..’7’ Else there will be positive overflow

Scanning a negative decimal int literal: If number scanned so far is less than 3276, which is max

32767 / 10, then scanning 1 more digit is safe, do number = number * 10 + ( c-'0’ ); But if number scanned so far is in critical range 3276, then

only some digits are safe, namely ‘0’..’8’ Else there will be negative overflow

Page 11: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

11

Check for Overflow in a2i()#define MAX 32767#define MAX10 3276 // i.e. integer divide 32767 / 10 = 3276. . .int a2i1( void ){ // a2i int number = 0; int neg = 0; if ( c == '-' ) {

neg = 1; c = getchar();

}else if ( c == '+' ) { c = getchar(); // keep neg = 0

} //end if while ( is_digit( c ) ) {

if ( number > MAX10 ) { printf( "Overflow 1. max = %d\n", MAX );

}else if ( number == MAX10 ) { if ( c == '9' ) {

printf( "Overflow 2. max = %d\n", MAX );

}else if ( c == '8' ) {if ( neg ) {

number = -32768;}else{

printf( "Overflow 3. max = %d\n", MAX );

} //end if }else{

number = number * 10 + ( c - '0' );

} //end if}else{

number = number * 10 + ( c - '0' ); } //end if

c = getchar(); } //end while return neg ? -number : number;} //end a2i

Page 12: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

12

Discuss Overflow in a2i The critical number = number * 10 + next digit is

performed only in safe state:

For positive state, if the next digit after 3276 is ‘0’..’7’ one more iteration of the multiply is safe; yielding <= 32767

For negative state, if the next digit after 3276 is ‘0’..’8’ one more iteration of the multiply is safe; yielding >= -32768

Similarly on a 32-bit or today’s 64-bit computer; the scanner for integer literals needs to be safe, and detect integer overflow before it happens

Common to have computers ignore integer overflow, so it may be safe to simply experience it, but the numeric value has to be safely scanned

Page 13: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

13

Maxint on 32-Bit

#include <iostream.h>

main(){ // main int expo; // shift 1 32 times unsigned long int pow = 1; // multiply repeatedly by 2

for ( expo = 1; expo <= 32; expo++ ) { pow = pow * 2; cout << " 2**" << expo << " = " << pow-1 << endl; } // end for cout << 0+4294967295 << endl; cout << 0-4294967295 << endl;} //end main

Page 14: 1 CS 162 Introduction to Computer Science Chapter 5 ASCII to Integer Conversion Herbert G. Mayer, PSU Status 11/9/2014

14

Maxint Output

2**1 = 1 2**2 = 3 2**3 = 7

. . .

2**14 = 16383 2**15 = 32767 2**16 = 65535 2**17 = 131071 2**18 = 262143 2**19 = 524287 2**20 = 1048575 2**21 = 2097151 2**22 = 4194303 2**23 = 8388607 2**24 = 16777215 2**25 = 33554431 2**26 = 67108863 2**27 = 134217727 2**28 = 268435455 2**29 = 536870911 2**30 = 1073741823 2**31 = 2147483647 2**32 = 429496729542949672951