Re: [MP3 ENCODER] castings (OT)
> It's taken from: > > Kerningham & Richie: Programming in C > > It's not a compiler, but a book. The German translation is *different* from > the original. Some additional remarks are taken from the ANSI Standard > (1990). Highly respectable source, but parts of the K&R syntax are now deprecated in Ansi C. Regards, -- Gabriel Bouvigne - France [EMAIL PROTECTED] mobile phone: [EMAIL PROTECTED] icq: 12138873 MP3' Tech: www.mp3-tech.org -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Frank Klemm schrieb am Mon, 18 Sep 2000: > #include > > float x = 1.5; > longy = 1234567890; > float y_float = 1234567890.0; > float a = 1.e32; > > int main (void) > { > double z = x * y; > > printf ( "%30.12f\n", z ); > printf ( "%30.12f\n", (float)x * (float)y );// this two lines > printf ( "%30.12f\n", (float)x * y_float ); // give a different result on gcc > printf ( "%30.12f\n", (double)x * (double)y ); > printf ( "a*a is %g, sizeof(a*a) is %u\n", a*a, sizeof(a*a) ); // ;-) > return 0; > } It is not surprising that above two lines give different results (assuming you use a Pentium class CPU/FPU): (float)y the long will be stored on the FPU stack in extended real format (80 bit) allowing full precision y_float the float (32 bit) will be loaded from memory and stored on the FPU stack in extended real format (80 bit), but precision is already lost. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
> From: "Frank Klemm" <[EMAIL PROTECTED]> > > a) char, signed char, short => int unless int cannot represent all possible values of char, in which case char => unsigned int > b) unsigned char, unsigned short => unsigned int if int can represent all possible values unsigned char, unsigned short => int otherwise unsigned char, unsigned short => unsigned int In essence, objects of type "smaller" than int are converted to int, unless int can't represent all values, in which case they're converted to unsigned int. Horribly platform-dependent. > c) float => double No. -- Mat. -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
> From: "Frank Klemm" <[EMAIL PROTECTED]> > > #include > > float x1 = 1.e30; > float x2 = 1.e31; > float x3 = 1.e32; > > int main ( void ) > { > float x4; > > x4 = x1*x2*x3 / (x1*x2 + x2*x3 + x3*x1); > > printf ( "%g\n", x4 ); > return 0; > } > > The code line x4=... is equivalent to > > x4 = (float) ((double)x1*x2*x3 / ((double)x1*x2 + (double)x2*x3 + (double)x3*x1)); No, that would be very bad for machines without hardware 'double' support. K&R1 did require that behaviour, though. (The change is explicitly noted in K&R2). > Note, that the optimizer of gcc-2.95 isn't standard conform. I don't doubt it. :) > One exception for implicit type conversations are functions calls of prototyped > functions (Note: Not in K&R2, but in ANSI C3.159-1989 and later). Exception from what? > PS: Nice try for MS VC++: > > unsigned __int64 x = 123456789012345LL; > doubley; > > y = x; Didn't they finally fix that in SP3? -- Mat. -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings (OT)
On Mon, Sep 18, 2000 at 08:17:46PM +0200, Robert Hegemann wrote: > > > > a) char, signed char, short => int > > b) unsigned char, unsigned short => unsigned int > > c) float => double > > So your Compiler/target CPU has only an affinity for some > elementary types. This is very special and different on > other Compilers/CPUs. > It's taken from: Kerningham & Richie: Programming in C It's not a compiler, but a book. The German translation is *different* from the original. Some additional remarks are taken from the ANSI Standard (1990). > >Second > > > > d) still different types? > > > > ldouble double ulong longuintint > > > > ldouble ldouble ldouble ldouble ldouble ldouble ldouble > > double ldouble double double double double double > > ulong ldouble double ulong ulong ulong ulong > > longldouble double ulong longulong long > > uintldouble double ulong ulong uintuint > > int ldouble double ulong longuintint > > > > float float gives a double. > > > Silly, you are saying above that it is fully wrong and then > telling the same at the bottom. > When it is the same it should be gave the same result. But it gave different results. Also tables are much nicer. Table lookup is faster and more error proof than text parsing ;-) -- Frank Klemm -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
On Sun, Sep 17, 2000 at 11:44:01PM +0200, Albert Faber wrote: > Lets take: float x = 1.5; longy = 1234567890; double z = x * y; printf ("%30.12f\n", z); > 1) one type is long double, the other will be casted to long double Not fulfilled. > 2) one type is double, the other will be casted to double Not fulfilled. > 3) one type is float, the other will be casted to float Fulfilled: Convert (long)1234567890 to (float)1234567936. > 4) one type is char, short int, enum or bitfield, the other will > be converted to int, if int can represent all values of the original > type; if not, the other type will be converted to unsigned int Not fulfilled. > 5) one type is unsigned long, the other will be unsigned long Not fulfilled. > 6) one type is long int and the other is unsigned int, then the unsigned > int type will be converted to long int, if long int can > represent all values of unsigned int. If this is not the case, > then both are converted to unsigned long int Not fulfilled. > 7) one type is long, the other will be converted to long Not fulfilled. > 8) one type is unsigned, the other will get unsigned Not fulfilled. > 9) is none of the above cases true, then both are of type int Not fulfilled. So the code should be equivalent to: double z = (float)1.5 * (float)1234567936; printf ("%30.12f\n", z); which not only looks like nonsense. But also gcc makes a lot of very strange things: #include float x = 1.5; longy = 1234567890; float y_float = 1234567890.0; float a = 1.e32; int main (void) { double z = x * y; printf ( "%30.12f\n", z ); printf ( "%30.12f\n", (float)x * (float)y );// this two lines printf ( "%30.12f\n", (float)x * y_float ); // give a different result on gcc printf ( "%30.12f\n", (double)x * (double)y ); printf ( "a*a is %g, sizeof(a*a) is %u\n", a*a, sizeof(a*a) ); // ;-) return 0; } Maybe Richie made an arrangement with the FORTRAN compiler builder to save their jobs for the next 50 years ;-) -- Frank Klemm Note: The background is that a float can't store all values of a signed long and an unsigned long. The integer range of a float is only -16777216...+16777216. For the same reason 64 bit ints should be auto casted to long double, not to double. -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
On Mon, Sep 18, 2000 at 06:40:23PM +0200, Robert Hegemann wrote: > Frank Klemm schrieb am Mon, 18 Sep 2000: > > :: > > :: 1) one type is long double, the other will be casted to long double > > :: 2) one type is double, the other will be casted to double > > :: 3) one type is float, the other will be casted to float > > Fully wrong. > > The rest I haven't checked. > > > > -- > > Mit freundlichen Grüßen > > Frank Klemm > > You may like to look into Microsoft Developer Studio's help > text, section "Usual Arithmetic Conversions", as you call > this to be wrong too. > Microsoft's Developer Studio is fine, but far beyond being standard conform. Gcc is a little bit better, especially with a lot of force-conformity flags. #include float x1 = 1.e30; float x2 = 1.e31; float x3 = 1.e32; int main ( void ) { float x4; x4 = x1*x2*x3 / (x1*x2 + x2*x3 + x3*x1); printf ( "%g\n", x4 ); return 0; } The code line x4=... is equivalent to x4 = (float) ((double)x1*x2*x3 / ((double)x1*x2 + (double)x2*x3 + (double)x3*x1)); Note, that the optimizer of gcc-2.95 isn't standard conform. One exception for implicit type conversations are functions calls of prototyped functions (Note: Not in K&R2, but in ANSI C3.159-1989 and later). -- Frank Klemm PS: Nice try for MS VC++: unsigned __int64 x = 123456789012345LL; doubley; y = x; -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Frank Klemm schrieb am Mon, 18 Sep 2000: > :: Hi Frank, > :: > :: > :: > :: > :: 1) one type is long double, the other will be casted to long double > :: > :: 2) one type is double, the other will be casted to double > :: > :: 3) one type is float, the other will be casted to float > :: > Fully wrong. > :: > The rest I haven't checked. > :: > > :: > :: Does it mean that you've tested the above? > :: If yes - how did you test this to be wrong? what is the compiler, > :: optimization options? > :: >First > > a) char, signed char, short => int > b) unsigned char, unsigned short => unsigned int > c) float => double So your Compiler/target CPU has only an affinity for some elementary types. This is very special and different on other Compilers/CPUs. >Second > > d) still different types? > > ldouble double ulong longuintint > > ldouble ldouble ldouble ldouble ldouble ldouble ldouble > doubleldouble double double double double double > ulong ldouble double ulong ulong ulong ulong > long ldouble double ulong longulong long > uint ldouble double ulong ulong uintuint > int ldouble double ulong longuintint > > float float gives a double. Silly, you are saying above that it is fully wrong and then telling the same at the bottom. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
:: Albert Faber schrieb am Son, 17 Sep 2000: :: > Robert, :: > So if i have the following piece of code :: > :: > int my_signed= -1; :: > unsigned int my_unsigned=10; :: > :: > if (my_signed>my_unsigned) :: > printf("my_singed > my_unsigned\n"); :: > else :: > printf("my_singed is <= my_unsigned\n"); :: > :: > It should print: "my_singed > my_unsigned\n" according to your implicit :: > casting rules, which can cause horrible unexpected run-time problems also. :: :: yes, it does! :: There is a package out there called LCLint. It finds a lot of such standard C bugs. It is free. Problems: * No C++ * Too sloppy * You must use this tool from the very beginning, otherwise you got several hundreds to thousands warnings per file. A lot of them are typical C pit falls lurking to become active ... Example: $ cat hello.c #include int main ( /*@unused@*/ int argc, /*@unused@*/ char** argv ) { int my_signed = -1; unsigned int my_unsigned = +10; if ( my_signed > my_unsigned ) printf ( "my_signed > my_unsigned\n" ); else printf ( "my_signed <= my_unsigned\n" ); return 0; } $ lint hello.c LCLint 2.4b --- 18 Apr 98 hello.c: (in function main) hello.c:8:10: Operands of > have incompatible types (int, unsigned int): my_signed > my_unsigned To ignore signs in type comparisons use +ignoresigns Finished LCLint checking --- 1 code error found $ _ The "/*@unused@*/" is to suppress: $ lint hello.c LCLint 2.4b --- 18 Apr 98 hello.c: (in function main) hello.c:8:10: Operands of > have incompatible types (int, unsigned int): my_signed > my_unsigned To ignore signs in type comparisons use +ignoresigns hello.c:3:16: Parameter argc not used A function parameter is not used in the body of the function. If the argument is needed for type compatibility or future plans, use /*@unused@*/ in the argument declaration. (-paramuse will suppress message) hello.c:3:29: Parameter argv not used Finished LCLint checking --- 3 code errors found -- Mit freundlichen Grüßen Frank Klemm eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
:: Hi Frank, :: :: > :: :: > :: 1)one type is long double, the other will be casted to long double :: > :: 2)one type is double, the other will be casted to double :: > :: 3)one type is float, the other will be casted to float :: > Fully wrong. :: > The rest I haven't checked. :: > :: :: Does it mean that you've tested the above? :: If yes - how did you test this to be wrong? what is the compiler, :: optimization options? :: First a) char, signed char, short => int b) unsigned char, unsigned short => unsigned int c) float => double Second d) still different types? ldouble double ulong longuintint ldouble ldouble ldouble ldouble ldouble ldouble ldouble double ldouble double double double double double ulong ldouble double ulong ulong ulong ulong longldouble double ulong longulong long uintldouble double ulong ulong uintuint int ldouble double ulong longuintint float float gives a double. Note that a lot of compilers modifying rule c) and d) using instead: c') float, double => long double d') still different types? ldouble double ulong longuintint ldouble ldouble ldouble ldouble ldouble ldouble ldouble double ldouble ldouble ldouble ldouble ldouble ldouble ulong ldouble ldouble ulong ulong ulong ulong longldouble ldouble ulong longulong long uintldouble ldouble ulong ulong uintuint int ldouble ldouble ulong longuintint On machines computing with 80 bit-IEEE floats rounding costs huge amounts of CPU time. But ANSI C forces this silly rounding on standard. >From the view of code optimization, C was a great milestone in the 70's, in the 2000's it is a millstone round the compiler builder's neck. Problems: * nearly no infrastructure * problems with 64 bit (problems with pointer <=> &array[index] transformation) * typical C structures are not very good for super scalar machines * pointer aliases avoid a lot of deep optimization on super scalar machines * low level standardization (nearly no demands on the hardware, so also 13 bit CPUs with 1's complement and really strange arithmetic (a+b-b!=a on overrun) can be supported). -- Mit freundlichen Grüßen Frank Klemm eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Frank Klemm schrieb am Mon, 18 Sep 2000: > :: > :: 1)one type is long double, the other will be casted to long double > :: 2)one type is double, the other will be casted to double > :: 3)one type is float, the other will be casted to float > Fully wrong. > The rest I haven't checked. > > -- > Mit freundlichen Grüßen > Frank Klemm You may like to look into Microsoft Developer Studio's help text, section "Usual Arithmetic Conversions", as you call this to be wrong too. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Hi Frank, > :: > :: 1)one type is long double, the other will be casted to long double > :: 2)one type is double, the other will be casted to double > :: 3)one type is float, the other will be casted to float > Fully wrong. > The rest I haven't checked. > Does it mean that you've tested the above? If yes - how did you test this to be wrong? what is the compiler, optimization options? -Leonid -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Frank Klemm schrieb am Mon, 18 Sep 2000: > :: > :: 1)one type is long double, the other will be casted to long double > :: 2)one type is double, the other will be casted to double > :: 3)one type is float, the other will be casted to float > Fully wrong. > The rest I haven't checked. You may tell this the authors of "Prgrammieren mit C++", Falko Bause, Wolfgang Tölle, ISBN 3-528-05324-0 > > -- > Mit freundlichen Grüßen > Frank Klemm > > eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] > phone | +49 (3641) 64-2721home: +49 (3641) 390545 > sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
:: :: Albert you are right, but this shows that it is necessary to be :: resolved, not casted. :: Compile programs with gnatmake, not with gcc ;-) -- Mit freundlichen Grüßen Frank Klemm PS: Ada programs are compiled with gnatmake. Make functionality is part of Ada itself. eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
:: :: 1) one type is long double, the other will be casted to long double :: 2) one type is double, the other will be casted to double :: 3) one type is float, the other will be casted to float Fully wrong. The rest I haven't checked. -- Mit freundlichen Grüßen Frank Klemm eMail | [EMAIL PROTECTED] home: [EMAIL PROTECTED] phone | +49 (3641) 64-2721home: +49 (3641) 390545 sMail | R.-Breitscheid-Str. 43, 07747 Jena, Germany -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Albert Faber schrieb am Son, 17 Sep 2000: > Robert, > So if i have the following piece of code > > int my_signed= -1; > unsigned int my_unsigned=10; > > if (my_signed>my_unsigned) > printf("my_singed > my_unsigned\n"); > else > printf("my_singed is <= my_unsigned\n"); > > It should print: "my_singed > my_unsigned\n" according to your implicit > casting rules, which can cause horrible unexpected run-time problems also. yes, it does! > Thus in this situation you have to assert that my_signed is >=0. The normal > practise will be that it is far more likely that my_signed <0 than > my_unsigned>MAX_INT > > Albert Albert you are right, but this shows that it is necessary to be resolved, not casted. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Robert, So if i have the following piece of code int my_signed= -1; unsigned int my_unsigned=10; if (my_signed>my_unsigned) printf("my_singed > my_unsigned\n"); else printf("my_singed is <= my_unsigned\n"); It should print: "my_singed > my_unsigned\n" according to your implicit casting rules, which can cause horrible unexpected run-time problems also. Thus in this situation you have to assert that my_signed is >=0. The normal practise will be that it is far more likely that my_signed <0 than my_unsigned>MAX_INT Albert - Original Message - From: "Robert Hegemann" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Sunday, September 17, 2000 10:34 PM Subject: Re: [MP3 ENCODER] castings Albert Faber schrieb am Son, 17 Sep 2000: > Robert, > And if you don't cast it, you will leave it up to the compiler, thus the > behavior becomes compiler specfic, will it cast the unsigned to a signed or > will it cast the signed to an unsigned value. What does happen, if you don't > cast, and assign my_signed to my_unsigned if my_unsinged > INT_MAX ?. What > it boils down to is that you have need have to perform assert, even when you > don't cast. And I agree, it is best to resolve the signed/unsigned conflicts > rather than casting the warning away. > > Albert If you have operands of different basic types in arithmetic expressions the implicit casting goes like this: 1) one type is long double, the other will be casted to long double 2) one type is double, the other will be casted to double 3) one type is float, the other will be casted to float 4) one type is char, short int, enum or bitfield, the other will be converted to int, if int can represent all values of the original type; if not, the other type will be converted to unsigned int 5) one type is unsigned long, the other will be unsigned long 6) one type is long int and the other is unsigned int, then the unsigned int type will be converted to long int, if long int can represent all values of unsigned int. If this is not the case, then both are converted to unsigned long int 7) one type is long, the other will be converted to long 8) one type is unsigned, the other will get unsigned 9) is none of the above cases true, then both are of type int in general: the "smaller" type will be converted to the "larger" type note: unsigned xxx is of larger type than signed xxx! The advantage of the compiler warnings is, that you *see* that there are some lines with some possibility to be buggy. If you cast those warnings away one thinks: "WOW, no errors nor warnings so all is good!" I'm happy to see that we agree about resolving the conflicts is the best way to handle them. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ ) -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Albert Faber schrieb am Son, 17 Sep 2000: > Robert, > And if you don't cast it, you will leave it up to the compiler, thus the > behavior becomes compiler specfic, will it cast the unsigned to a signed or > will it cast the signed to an unsigned value. What does happen, if you don't > cast, and assign my_signed to my_unsigned if my_unsinged > INT_MAX ?. What > it boils down to is that you have need have to perform assert, even when you > don't cast. And I agree, it is best to resolve the signed/unsigned conflicts > rather than casting the warning away. > > Albert If you have operands of different basic types in arithmetic expressions the implicit casting goes like this: 1) one type is long double, the other will be casted to long double 2) one type is double, the other will be casted to double 3) one type is float, the other will be casted to float 4) one type is char, short int, enum or bitfield, the other will be converted to int, if int can represent all values of the original type; if not, the other type will be converted to unsigned int 5) one type is unsigned long, the other will be unsigned long 6) one type is long int and the other is unsigned int, then the unsigned int type will be converted to long int, if long int can represent all values of unsigned int. If this is not the case, then both are converted to unsigned long int 7) one type is long, the other will be converted to long 8) one type is unsigned, the other will get unsigned 9) is none of the above cases true, then both are of type int in general: the "smaller" type will be converted to the "larger" type note: unsigned xxx is of larger type than signed xxx! The advantage of the compiler warnings is, that you *see* that there are some lines with some possibility to be buggy. If you cast those warnings away one thinks: "WOW, no errors nor warnings so all is good!" I'm happy to see that we agree about resolving the conflicts is the best way to handle them. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
Re: [MP3 ENCODER] castings
Robert, And if you don't cast it, you will leave it up to the compiler, thus the behavior becomes compiler specfic, will it cast the unsigned to a signed or will it cast the signed to an unsigned value. What does happen, if you don't cast, and assign my_signed to my_unsigned if my_unsinged > INT_MAX ?. What it boils down to is that you have need have to perform assert, even when you don't cast. And I agree, it is best to resolve the signed/unsigned conflicts rather than casting the warning away. Albert - Original Message - From: "Robert Hegemann" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Sunday, September 17, 2000 6:50 PM Subject: [MP3 ENCODER] castings Hi all, I see a tendency that compiler warnings get casted away. The problem is, that these castings make your compiler happy, but there is a high potential that this only covers BUGS. Everytime someone will cast away compiler warnings he should back up his change with an assertion! For example, casting an unsigned to a signed int: assert(my_unsinged <= INT_MAX); my_signed = (int)my_unsigned; Also, don't get into the habit of becoming a slave of your compiler. If there are ambiguities, try to solve them without castings. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ ) -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )
[MP3 ENCODER] castings
Hi all, I see a tendency that compiler warnings get casted away. The problem is, that these castings make your compiler happy, but there is a high potential that this only covers BUGS. Everytime someone will cast away compiler warnings he should back up his change with an assertion! For example, casting an unsigned to a signed int: assert(my_unsinged <= INT_MAX); my_signed = (int)my_unsigned; Also, don't get into the habit of becoming a slave of your compiler. If there are ambiguities, try to solve them without castings. Ciao Robert -- MP3 ENCODER mailing list ( http://geek.rcc.se/mp3encoder/ )