Re: Question for a REAL expert on casting double to float...
- From: "Bill Reid" <hormelfree@xxxxxxxxxxxxxxxx>
- Date: Sun, 13 Jul 2008 02:05:55 GMT
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"since
<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,
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
.
- Follow-Ups:
- Re: Question for a REAL expert on casting double to float...
- From: Ben Bacarisse
- Re: Question for a REAL expert on casting double to float...
- From: Ian Collins
- Re: Question for a REAL expert on casting double to float...
- References:
- Question for a REAL expert on casting double to float...
- From: Bill Reid
- Re: Question for a REAL expert on casting double to float...
- From: Raymond Martineau
- Question for a REAL expert on casting double to float...
- Prev by Date: Re: Comment on trim string function please
- Next by Date: Re: AFL (Australian Football League)
- Previous by thread: Re: Question for a REAL expert on casting double to float...
- Next by thread: Re: Question for a REAL expert on casting double to float...
- Index(es):
Relevant Pages
|