Re: Question for a REAL expert on casting double to float...




OK, I've read all the responses so far (three), I guess I've got it figured
out...I still have an outstanding question/confusion, though...

Raymond Martineau <bk039@xxxxxx> wrote in message
news:oggi74lloft717l11ch6ujcisf9h1c3lib@xxxxxxxxxx
On Sat, 12 Jul 2008 21:17:54 GMT, "Bill Reid"
<hormelfree@xxxxxxxxxxxxxxxx> wrote:

I just noticed that my "improved" version of sscanf() doesn't assign
floating point numbers properly if the variable assigned to is declared
as a "float" rather than a "double". (This never cropped up before,
since
I rarely use "float"s for anything, and hardly ever use the function for
floating-point numbers in the first place; I just was messing around
testing it for all cases and noticed a problem.)

[...]

The problem is when I get down to the point of actually assigning
values to the pointers:

switch(*format_buf) {

case 'd' :
copy_max_length_text(number_buf,field,field_length);
*va_arg(var_argument,unsigned long *)=
strtoul(number_buf,NULL,10);
break;

Scanf actually treats "%d" as a signed integer. If you want to use a
long, you probably want to have %ld instead.

Except it hardly matters in REAL *scanf() functions what you use
as a specifier for integer numbers, but I haven't checked my "fake"
scan_line() for this case (I just use this to assign to an "unsigned"
which has the same sizeof() as "unsigned long" on my system).

This is probably the heart of my confusion; you can kind of do
anything with integers, but floating-point numbers are "touchier"...I
have a long history of completely abusing the format specifiers
for integers (I rarely if ever get them right) in *scanf() functions
without noticeable problems, so when wrote my own scan_line()
I blew off full checking of the complete format specifier for "floats"
as well...

case 'f' :
copy_max_length_text(number_buf,field,field_length);
*va_arg(var_argument,double *)=strtod(number_buf,NULL);
break;

In this case, sscanf uses %f for a float rather than a double. If you
want it to work exactly like scanf, change the double* to float*, and
add handling for %lf.

Yeah, that works...and of course there is no other way I can see
to get it to work, and that's EXACTLY how *scanf() functions work,
so that's the answer...

In general, you need to add a case for 'l' and set a flag indicating
that you are dealing with a long/double instead of an int/float. If
you don't have the handling for this flag, you won't get the expected
result.

OK, I have spent a few minutes this afternoon re-writing the
loop to check the full format specifier (or at least my still abbreviated
version of the format specifiers) for the correct action, so it works
EXACTLY as you've said.

My REAL question NOW is: this must have something to do
with fundamental promotions/assignments, not anything to do
with *scanf() or my "fake" scan_line() per se, right? Why else
the big difference between integer types and float types? I was
also confused about exactly how the "type" argument for
va_arg() worked, I thought it HAD to be the EXACT same
type as the return value of the conversion function (strtod()).

---
William Ernest Reid



.



Relevant Pages

  • Re: Question for a REAL expert on casting double to float...
    ... Scanf actually treats "%d" as a signed integer. ... sscanf uses %f for a float rather than a double. ... version of the format specifiers) for the correct action, ... floating point input format. ...
    (comp.lang.c)
  • Re: Question for a REAL expert on casting double to float...
    ... scanf; ... want it to work exactly like scanf, change the double* to float*, and ... abbreviated version of the format specifiers) for the correct action, ... floating point input format. ...
    (comp.lang.c)
  • Re: scanf for char input getting skipped
    ... of discovering that scanf isn't as clever as he thought. ... float hours_worked = 0; ... Please enter the employee's clock number: ... Employee Clock Number Hourly Rate Hours Worked Gross ...
    (comp.lang.c)
  • Re: verify float number
    ... scanf returns the number of fields that it successfully read. ... field to be a float, it successfully read one float value. ... I need to verify that a number ... Boeing Associate Technical Fellow ...
    (comp.lang.c)
  • Re: data type for decimal number
    ... You can't pass a float as one of the optional parameters of a variadic ... Actually, %x takes an int, not a hex. ... C doesn't have a hex type. ... then you can use the format specifiers used for float. ...
    (comp.lang.c)