Prev: NET tips to expand your biz
Next: IR is insane
From: Jamie on 25 Mar 2010 21:24 Grant Edwards wrote: > On 2010-03-24, Jamie <jamie_ka1lpa_not_valid_after_ka1lpa_(a)charter.net> wrote: > > >>Last time I knew, that just cast the object into what you want, but it's >>not going to magically convert a FLOAT to a unsigned char.. > > > That's exactly what a cast does. (Though there's nothing magical > about the conversion -- it's a well-defined operation.) > > >> Its only going to instruct the compiler that the contents of memory the >>"F" occupies is a unsigned char and simply moves the data from that >>from ever it is in memory to "u" > > > No, it isn't. It instructs the compiler to do the conversion. > > >> simply speaking.. >> u = f; isn't the same as u = (unsigned char) f; where I come from.. > > > I'm not sure where you come from. Here on Earth, when using the C > language, it's exactly the same. > > Here's an example program: > > > extern volatile unsigned char u1,u2; > extern volatile float f; > > void foo1(void) > { > u1 = f; > } > > void foo2(void) > { > u2 = (unsigned char)f; > } > > And here's the generated code using gcc for IA32. Note that the code > generated for the two cases is identical: > > .file "testit.c" > .text > .p2align 4,,15 > .globl foo1 > .type foo1, @function > foo1: > subl $8, %esp > fnstcw 6(%esp) > flds f > movzwl 6(%esp), %eax > movb $12, %ah > movw %ax, 4(%esp) > fldcw 4(%esp) > fistps 2(%esp) > fldcw 6(%esp) > movzwl 2(%esp), %eax > movb %al, u1 > addl $8, %esp > ret > .size foo1, .-foo1 > .p2align 4,,15 > .globl foo2 > .type foo2, @function > foo2: > subl $8, %esp > fnstcw 6(%esp) > flds f > movzwl 6(%esp), %eax > movb $12, %ah > movw %ax, 4(%esp) > fldcw 4(%esp) > fistps 2(%esp) > fldcw 6(%esp) > movzwl 2(%esp), %eax > movb %al, u2 > addl $8, %esp > ret > .size foo2, .-foo2 > .ident "GCC: (Gentoo 4.3.4 p1.0, pie-10.1.5) 4.3.4" > .section .note.GNU-stack,"",@progbits > > > > >> And the last time I knew, AVR's do not have native support for >>floating point math. UNless I've been out of the loop here? > > > Doesn't matter. > > >> Instead, the compiler should be loading a default RTL that contains >>low level code to give you that results.. This of course is compiler >>linked and thus, makes it look natural to you, the coder. > > > No idea what your point is. > > >> And if the C compiler is standardized like most other compilers.. >> >> u = (unsigned char) f; simply tells the compiler to treat the object >> of "F" as if it was a char instead. No conversion is taking >>place here. > > > Yes, a conversion _is_ taking place here. That's what a cast _is_: > it's an explicit conversion operation. > > >> As far as how the floats are implemented for the binary format of >>this compiler will dictate what value of data will be returned.. > > > No, it won't. It will take the integer portion of the float value and > store that value (modulo 256) into the unsigned char. > > >> I can only assume it may support the Mantissa and other elements >>of a floating point number, in which case, the above will not work as >>you may think.. >> But who am I, I don't know anything.. > > > I wouldn't say you don't know anything, but you don't seem to know > what a typecast does in a C program. > > >> stick with the "u = f;" and the compiler should be happy with that >>and call one of it's floattointeger conversion TRL functions.. But If >>you want to know how the float if constructed to represent a floating >>point number, I guess you could hack it with the cast. I think only >>the authors of the compiler would understand it's meanings.. > > > A typecast doesn't to at all what you think it does. > Well I may have had a brain scrub on that one, I'll admit to that how ever. This will produced what I was talking about. u2 = *(unsigned int *) &f; I would be very surprised if the gcc-AVR compiler could handle that..
From: Grant Edwards on 25 Mar 2010 20:59 On 2010-03-26, Jamie <jamie_ka1lpa_not_valid_after_ka1lpa_(a)charter.net> wrote: >> A typecast doesn't to at all what you think it does. > > Well I may have had a brain scrub on that one, I'll admit to that how ever. > This will produced what I was talking about. Yep. > u2 = *(unsigned int *) &f; > > I would be very surprised if the gcc-AVR compiler could handle that.. I've used the gcc-avr compiler, and it will handle that just fine. -- Grant
From: Dave Platt on 25 Mar 2010 21:25 In article <h9Tqn.301415$OX4.301351(a)newsfe25.iad>, Jamie <jamie_ka1lpa_not_valid_after_ka1lpa_(a)charter.net> wrote: >Well I may have had a brain scrub on that one, I'll admit to that how ever. > This will produced what I was talking about. > > u2 = *(unsigned int *) &f; Yeah, that's the sort of construct that has the effect you were thinking about. It's incredibly non-portable, ill-defined, and "How lucky do you feel today?" If you do it the other way (e.g.) f2 = *(unsigned float *) &u2; thing could be even worse, due to misalignment issues. Segfaults are entirely possible on many architectures. -- Dave Platt <dplatt(a)radagast.org> AE6EO Friends of Jade Warrior home page: http://www.radagast.org/jade-warrior I do _not_ wish to receive unsolicited commercial email, and I will boycott any company which has the gall to send me such ads!
From: David Brown on 26 Mar 2010 03:14 Dave Platt wrote: > In article <h9Tqn.301415$OX4.301351(a)newsfe25.iad>, > Jamie <jamie_ka1lpa_not_valid_after_ka1lpa_(a)charter.net> wrote: > >> Well I may have had a brain scrub on that one, I'll admit to that how ever. >> This will produced what I was talking about. >> >> u2 = *(unsigned int *) &f; > > Yeah, that's the sort of construct that has the effect you were > thinking about. It's incredibly non-portable, ill-defined, and "How > lucky do you feel today?" > I am not sure if such statements are well-defined in terms of C standards, but they are well-defined in practice. You are reading the underlying memory pattern for the float. It's going to be dependent on the compiler/library combination for the format (though almost all compilers, including avr-gcc, use IEEE format), the endianness, and possibly alignment issues of the particular cpu. But it is certainly valid and consistent to use pointer casts like this. If you've ever used memcpy to copy a struct containing floats, you've effectively done this already. And you'll see code like that in the library implementation of software floating point routines - that's how the floating point data is broken up and interpreted to carry out the calculations in integer operations. > If you do it the other way (e.g.) > > f2 = *(unsigned float *) &u2; > > thing could be even worse, due to misalignment issues. Segfaults are > entirely possible on many architectures. > I haven't seen an "unsigned float" before - guess that's a typo. But yes, you always have to look out for alignment issues when mixing pointers to objects of different sizes. Of course, on an 8-bit avr, everything is aligned!
From: David Brown on 26 Mar 2010 03:58
On 26/03/2010 02:24, Jamie wrote: > Grant Edwards wrote: > >> On 2010-03-24, Jamie >> <jamie_ka1lpa_not_valid_after_ka1lpa_(a)charter.net> wrote: <snip> >> A typecast doesn't to at all what you think it does. >> > Well I may have had a brain scrub on that one, I'll admit to that how ever. > This will produced what I was talking about. > > u2 = *(unsigned int *) &f; > > I would be very surprised if the gcc-AVR compiler could handle that.. > What are you expecting when you say "handle that"? If you are expecting the standard C behaviour - that u2 will get part of the underlying memory pattern of the float - then avr-gcc will handle it perfectly well, just like any other C compiler. But if you are equally wrong about this sort of cast as you were with non-pointer casts, and think the compiler should do a floating-point to integer conversion, then you will be disappointed - that's not how C works, and therefore not how avr-gcc works. |