Welcome Guest ( Log In | Register )

Outline · [ Standard ] · Linear+

 C++ help debug error, from bank account system

views
     
TSKaraKuri
post Apr 16 2014, 04:11 PM, updated 10y ago

New Member
*
Junior Member
4 posts

Joined: Mar 2014
Im doing my assignment from school while debugging i encounter this error :Warning 2


warning C4244: '=' : conversion from 'double' to 'char', possible loss of data

what to do with it? the line of the error :


accountNum[i] = (series / pow(10, 8 - i)) + '0';

can any sifu help regarding this? im noob/new in programming
Lord Tiki Mick
post Apr 16 2014, 04:35 PM

Regular
******
Senior Member
1,018 posts

Joined: Jul 2012
CODE

(series / pow(10, 8 - i)) <--- this possibly would return double
'0' <-- this is char
accountNum <-- I reckon you declare this as char array

This, char = double + char, you will get char. With the double value is converted into char. Char only contain 1 byte of data, while double contains more than that. When you convert double to char, only 1 byte of the double is stored in the variable, the rest is lost, hence the warning.

It's like you have 1 litter of bottle, but you tried to fill it with 10 litter of water.

This post has been edited by Lord Tiki Mick: Apr 17 2014, 10:58 AM
TheSolver
post Apr 16 2014, 04:35 PM

Regular
******
Senior Member
1,108 posts

Joined: Jun 2011
If you intend to do as the warning says, and then to silence the warning in one go, why not cast to 'char' (or to 'int' even) explicitly.
ISawYou
post Apr 16 2014, 05:34 PM

On my way
****
Senior Member
531 posts

Joined: Oct 2011
From: Tawau -> Menumbok, Sabah(Land Below The Wind)



You should declare

char accountNum[]
TheSolver
post Apr 16 2014, 06:25 PM

Regular
******
Senior Member
1,108 posts

Joined: Jun 2011
QUOTE(ISawYou @ Apr 16 2014, 05:34 PM)
You should declare

char accountNum[]
*
TS must have already declared and defined the array accountNum. That whys when it's element is a LHS it expects a char type at most without warnings.

Besides, your declaration is illegal. smile.gif
TheSolver
post Apr 16 2014, 06:31 PM

Regular
******
Senior Member
1,108 posts

Joined: Jun 2011
'0' is an int literal not a char type. Yes I mean the one with the single quotes, and not limited the integer 0. That means it tends to occupy 4 bytes* on Intel rather than a single byte of 'char' type.

*YMMV depending the OS and arch.

This post has been edited by TheSolver: Apr 16 2014, 06:34 PM
dstl1128
post Apr 17 2014, 10:09 AM

Look at all my stars!!
*******
Senior Member
4,463 posts

Joined: Jan 2003
char is 1 byte.

So it's like you have 1 litter of bottle, but you tried to fill it with 8 litter of water (double is 8 bytes).

If you know what you are doing then you can just ignore that warning, or cast your result just to silence the compiler warning.




Lord Tiki Mick
post Apr 17 2014, 10:57 AM

Regular
******
Senior Member
1,018 posts

Joined: Jul 2012
QUOTE(dstl1128 @ Apr 17 2014, 10:09 AM)
char is 1 byte.

So it's like you have 1 litter of bottle, but you tried to fill it with 8 litter of water (double is 8 bytes).

If you know what you are doing then you can just ignore that warning, or cast your result just to silence the compiler warning.
*
My previous post was wrong. I said char is two bytes, when it's actually a single byte. sweat.gif
Lord Tiki Mick
post Apr 17 2014, 11:24 AM

Regular
******
Senior Member
1,018 posts

Joined: Jul 2012
QUOTE(TheSolver @ Apr 16 2014, 06:31 PM)
'0' is an int literal not a char type. Yes I mean the one with the single quotes, and not limited the integer 0. That means it tends to occupy 4 bytes* on Intel rather than a single byte of 'char' type.

*YMMV depending the OS and arch.
*
Although '0' is stored in 4 bytes of data, I don't think calling an expressions with single quotes as a int literal is correct. Because everything enclosed within two single quotes are single byte values. It can't never be 4 bytes. You can't compile '\37777777777' (4 byte) but you can compile '\377' (1 byte).

Btw, KaraKuri, this is how you make the warning disappear:
CODE

accountNum[i] = ((char) (series / pow(10, 8 - i))) + '0';
// Or without the extra parenthesis:
accountNum[i] = (char) (series / pow(10, 8 - i)) + '0';

This means, calculate series divided by 108-i, convert it to char, then add it with '0' (48) and store the result as char (1 byte).

This post has been edited by Lord Tiki Mick: Apr 17 2014, 11:35 AM
TheSolver
post Apr 22 2014, 11:13 AM

Regular
******
Senior Member
1,108 posts

Joined: Jun 2011
QUOTE(Lord Tiki Mick @ Apr 17 2014, 11:24 AM)
Although '0' is stored in 4 bytes of data, I don't think calling an expressions with single quotes as a int literal is correct. Because everything enclosed within two single quotes are single byte values. It can't never be 4 bytes. You can't compile '\37777777777' (4 byte) but you can compile '\377' (1 byte).

Btw, KaraKuri, this is how you make the warning disappear:
CODE

accountNum[i] = ((char) (series / pow(10, 8 - i))) + '0';
// Or without the extra parenthesis:
accountNum[i] = (char) (series / pow(10, 8 - i)) + '0';

This means, calculate series divided by 108-i, convert it to char, then add it with '0' (48) and store the result as char (1 byte).
*
I must have missed this response to my post.

Here are the answers to your doubts.

1. How does the compiler handle the representation of EOF? This is supposed to be like any character as far as C is concerned.

2. If your assertion is correct, this expression wouldn't have been promoted to int by default:
QUOTE
((char) (series / pow(10, 8 - i))) + '0'
Or to put it differently, C tries to fit the widest possible container* to avoid precision loss. Thus the largest is the container holding '0' and the width is the same as int width and is greater than 1;

Try this to be sure on your computer, any computer smile.gif
CODE

if (sizeof '0' == sizeof(int))
 printf("'0' is an int or happens to take the int width\n");
else
 printf("'0' is in NO circumstances an int\n");


* This is not Java container. Just a hypothetical container.
Lord Tiki Mick
post Apr 22 2014, 11:37 AM

Regular
******
Senior Member
1,018 posts

Joined: Jul 2012
QUOTE(TheSolver @ Apr 22 2014, 11:13 AM)
I must have missed this response to my post.

Here are the answers to your doubts.

1. How does the compiler handle the representation of EOF? This is supposed to be like any character as far as C is concerned.

2. If your assertion is correct, this expression wouldn't have been promoted to int by default:

Or to put it differently, C tries to fit the widest possible container* to avoid precision loss. Thus the largest is the container holding '0' and the width is the same as int width and is greater than 1;

Try this to be sure on your computer, any computer  smile.gif
CODE

if (sizeof '0' == sizeof(int))
 printf("'0' is an int or happens to take the int width\n");
else
 printf("'0' is in NO circumstances an int\n");


* This is not Java container. Just a hypothetical container.
*
If you read properly my previous post, I already know that the size of '0' is 4 bytes, which is the size of int. And I also know that '0' means 48. I only questioned you saying '0' is an integer literal. You're not fully wrong though, and I might be wrong, since every char is an integer, but every integer is not a char. But I strongly believe, '0' should be called a char literal, and 48 is an integer literal.

I also believe, y = '0' + x, where x and y are char variables would compile as long as '0' + x < 256. EOF have the value of -1, which is 255 (0xFF) in char.
TheSolver
post Apr 22 2014, 12:45 PM

Regular
******
Senior Member
1,108 posts

Joined: Jun 2011
QUOTE(Lord Tiki Mick @ Apr 22 2014, 11:37 AM)
If you read properly my previous post, I already know that the size of '0' is 4 bytes, which is the size of int. And I also know that '0' means 48. I only questioned you saying '0' is an integer literal. You're not fully wrong though, and I might be wrong, since every char is an integer, but every integer is not a char. But I strongly believe, '0' should be called a char literal, and 48 is an integer literal.

I also believe, y = '0' + x, where x and y are char variables would compile as long as '0' + x < 256. EOF have the value of -1, which is 255 (0xFF) in char.
*
What makes you think EOF should be represented as char literal? All compiler implementations set EOF to the int value (not "unsigned int", and certainly not a "char" value).

Consider these:
0 is an integer representation of literal `'\0'`* or character literal '\0' or NUL character.
'0' is an integer representation of literal `'0'` or character literal '0'.

Think at many different levels will shed some light. Or better still, ponder the C Language specs about this.

Have you tried my small code snippet above to try on your computer yet? It answers your question.

* I don't use "" so that not to confuse with the NUL terminated string..
Lord Tiki Mick
post Apr 22 2014, 01:23 PM

Regular
******
Senior Member
1,018 posts

Joined: Jul 2012
QUOTE(TheSolver @ Apr 22 2014, 12:45 PM)
What makes you think EOF should be represented as char literal? All compiler implementations set EOF to the int value (not "unsigned int",  and certainly not a "char" value).

Consider these:
0 is an integer representation of literal `'\0'`* or character literal '\0' or NUL character.
'0' is an integer representation of literal `'0'` or character literal '0'.

Think at many different levels will shed some light. Or better still, ponder the C Language specs about this.

Have you tried my small code snippet above to try on your computer yet? It answers your question.

* I don't use "" so that not to confuse with the NUL terminated string..
*
I only said EOF have the value of -1, I didn't specifically mentioned it was a char. Why do you insists on making me try the snippet? sizeof '0' != sizeof(int)? I have mentioned twice, sizeof '0' = 4, and sizeof(int) = 4 in English didn't I?

'0' is indeed will return an integer of size 4 bytes, but I insists that it's a char literal because the fact that the value of any character inside a pair of single quotes is less than 256 which is what char is. Chars are integers, but their values less than 256. Char containers have single byte size because of that. That is all. I'm just rephrasing my previous points.
TheSolver
post Apr 22 2014, 01:58 PM

Regular
******
Senior Member
1,108 posts

Joined: Jun 2011
QUOTE(Lord Tiki Mick @ Apr 22 2014, 01:23 PM)
I only said EOF have the value of -1, I didn't specifically mentioned it was a char. Why do you insists on making me try the snippet? sizeof '0' != sizeof(int)? I have mentioned twice, sizeof '0' = 4, and sizeof(int) = 4 in English didn't I?

'0' is indeed will return an integer of size 4 bytes, but I insists that it's a char literal because the fact that the value of any character inside a pair of single quotes is less than 256 which is what char is. Chars are integers, but their values less than 256. Char containers have single byte size because of that. That is all. I'm just rephrasing my previous points.
*
From this quote
QUOTE
...literals of a given type are generally a token type, with a grammar rule, like "a string of digits" for an integer literal. Some literals are specific keywords, like true for the boolean literal "true".
...

what can you understand from an integer literal?

And a char is not limited to 8 bits. Some architecture has 10-bit char. And EOF doesn't have to be -1 either. It is up to the implementation, and it is just a coincident by convention.

Being clear on this fact, it will save you from common novice mistakes of base-n number handling.

Lord Tiki Mick
post Apr 22 2014, 01:59 PM

Regular
******
Senior Member
1,018 posts

Joined: Jul 2012
QUOTE(TheSolver @ Apr 22 2014, 01:58 PM)
From this quote

what can you understand from an integer literal?

And a char is not limited to 8 bits. Some architecture has 10-bit char. And EOF doesn't have to be -1 either. It is up to the implementation, and it is just a coincident by convention.

Being clear on this fact, it will save you from common novice mistakes of base-n number handling.
*
Ok, I admit that I am wrong.
RookieDaddy
post Apr 23 2014, 01:26 PM

Getting Started
**
Junior Member
160 posts

Joined: Nov 2008


nothing to add to TP as answers already provided... but very interesting discussions and references made to C standard... smile.gif

as the Topic Starter is asking C++, allow me to quote the C++11 language specifications § 2.14.3 paragraph 1:
QUOTE
A character literal is one or more characters enclosed in single quotes, as in ’x’, optionally preceded by
one of the letters u, U, or L, as in u’y’, U’z’, or L’x’, respectively. A character literal that does not begin
with u, U, or L is an ordinary character literal, also referred to as a narrow-character literal. An ordinary
character literal that contains a single c-char has type char
, with value equal to the numerical value of the
encoding of the c-char in the execution character set. An ordinary character literal that contains more than
one c-char is a multicharacter literal. A multicharacter literal has type int and implementation-defined
value.
and let me quote from the C11 language specifications § 6.4.4.4 paragraph 10:
QUOTE
An integer character constant has type int. The value of an integer character constant
containing a single character that maps to a single-byte execution character is the
numerical value of the representation of the mapped character interpreted as an integer.

The value of an integer character constant containing more than one character (e.g.,
'ab'), or containing a character or escape sequence that does not map to a single-byte
execution character, is implementation-defined. If an integer character constant contains
a single character or escape sequence, its value is the one that results when an object with
type char whose value is that of the single character or escape sequence is converted to
type int.
it's also interesting to know that in the C++11 specifications, there is a special section that talks about C Compatibility:
QUOTE
Change: Type of character literal is changed from int to char

Rationale: This is needed for improved overloaded function argument type matching. For example:
    int function( int i );
    int function( char c );
    function( ’x’ );
    It is preferable that this call match the second version of function rather than the first.

Effect on original feature: Change to semantics of well-defined feature. ISO C programs which depend on
    sizeof(’x’) == sizeof(int)
    will not work the same as C ++ programs.

Difficulty of converting: Simple.

How widely used: Programs which depend upon sizeof(’x’) are probably rare.
so the following code snippets will produce slightly different output in C++ vs C:
CODE

char c = '0';
cout << "size of '0': " << sizeof('0') << endl;
cout << "size of c  : " << sizeof(c) << endl;
cout << "size of char: " << sizeof(char) << endl;

output (C++):
CODE

size of '0': 1
size of c  : 1
size of char: 1


equivalent code snippets in C:
CODE

char c = '0';

printf("size of '0': %u\n", sizeof('0'));
printf("size of c  : %u\n", sizeof(c));
printf("size of char: %u\n", sizeof(char));

output ( C ):
CODE

size of '0': 4
size of c  : 1
size of char: 1


and output using 16-bit Turbo C:
CODE

size of '0': 2
size of c  : 1
size of char: 1


all these bring back some fond memories... thanks guys thumbup.gif

 

Change to:
| Lo-Fi Version
0.0172sec    0.33    5 queries    GZIP Disabled
Time is now: 29th March 2024 - 02:55 PM