关于铸造double to float的真实专家的问题...... [英] Question for a REAL expert on casting double to float...

查看:68
本文介绍了关于铸造double to float的真实专家的问题......的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我刚注意到我的改进了如果分配给的变量被声明为

为浮动,则sscanf()的版本不会正确分配

浮点数。而不是双重。 (这从来没有出现过,因为

我很少使用浮动来做任何事情,并且几乎没有使用函数来获得

浮点数;我只是搞乱了

测试它的所有情况并注意到一个问题。)


无论如何,它被声明并且我假设在很大程度上定义相同

方式sscanf()是:


int scan_line(char * line,char * format,...){

va_list var_argument;


/ *循环将格式字符串与参数列表匹配并分配给

指针* /

}


问题是当我到指点实际分配

值时:


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;


case'' F ':

copy_max_length_text(number_buf,field,field_length);

* va_arg(var_argument,double *)= strtod(number_buf,NULL);

break;


case''s'':

copy_max_length_text

(va_arg(var_argument,char *),field, field_length);

休息;


....


" case''f''" ;被分配为0.0000 ...如果参数实际上将

指向一个浮点数,但可以正常分配给一个双精度数。可能会有一些东西

这里我很想丢失,但是因为var_arg()的默认促销,<

变量参数列表,我感到很困惑,

但我不确定这里的问题是什么......


我假设必须有可能做到这一点,因为sscanf()

做得对,但就像我说我可能会错过一些非常简单的东西...... b $ b简单...


---

William Ernest Reid


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.)

Anyway, it is declared and I assume largely defined the same
way sscanf() is:

int scan_line(char *line,char *format,...) {
va_list var_argument;

/* loop to match up format string with argument list and assign to
pointers */
}

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;

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

case ''s'' :
copy_max_length_text
(va_arg(var_argument,char *),field,field_length);
break;

....

"case ''f''" is assigned as 0.0000... if the argument actually points
to a float, but works OK assigned to a double. There may be something
simple I''m missing here, but I get confused enough working with
variable argument list, because of the default promotions of var_arg(),
but I''m not sure that is even the issue here...

I''m assuming it must be possible to do this right, since sscanf()
does it right, but like I say I''m probably missing something very
simple...

---
William Ernest Reid

推荐答案

>我刚注意到我的改进了 ;如果分配给的变量被声明为浮动,则sscanf()的版本不会分配
>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.)



默认参数促销不会提升指针浮动

到指向双倍的指针。你对sscanf()的参数应该是

指针(对于格式字符串和那些与

转换相匹配的参数)。


并且机会是漂浮的,双倍的是不同的大小(它们不是b $ b必须是,但在大多数平台上都是如此),双倍是

更大,所以你可能会有越界的内存踩踏,

不要说浮动的位置不在同一个地方而且

加倍。 br />

The default argument promotions do not promote "pointer to float"
to "pointer to double". Your arguments to sscanf() should be
pointers (for the format string and those arguments matching a
conversion).

And chances are float and double are of different size (they don''t
have to be but it''s true on most platforms), with double being
bigger, so you''ll probably have out-of-bounds memory stomping, to
say nothing of the bits not being in the same place for float and
double.


>问题是当我到达为指针实际分配
值的时候:


开关(* format_buf){


case''d'':

copy_max_length_text(number_buf,field,field_length);

* va_arg(var_argument,unsigned long *)=
>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 *)=



如果它是%d,则参数为int *。如果它是%ld,则参数为

a long *。

If it''s a %d, the argument is an int *. If it''s a %ld, the argument is
a long *.


strtoul(number_buf,NULL,10);

休息;


case'' f'':

copy_max_length_text(number_buf,field,field_length);

* va_arg(var_argument,double *)= strtod(number_buf,NULL);
strtoul(number_buf,NULL,10);
break;

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



如果它是%f,则参数为float *。如果它是%lf,则参数

是双*。

If it''s %f, the argument is a float *. If it''s a %lf, the argument
is a double *.


break;


case''s'':

copy_max_length_text

(va_arg(var_argument,char *),field,field_length);

break ;

...
break;

case ''s'' :
copy_max_length_text
(va_arg(var_argument,char *),field,field_length);
break;

...


" Bill Reid" < ho ******** @ happyhealthy.netwrites:
"Bill Reid" <ho********@happyhealthy.netwrites:

我刚注意到我的改进了如果分配给的变量被声明为

为浮动,则sscanf()的版本不会正确分配

浮点数。而不是双重。
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".



< snip>

<snip>


无论如何,它被声明并且我假设在很大程度上定义了相同的

方式sscanf()是:


int scan_line(char * line,char * format,...){

va_list var_argument;


/ * loop匹配格式带参数列表的字符串并分配给

指针* /

}


问题是当我到达点的时候实际上为指针分配了

值:


开关(* format_buf){


case''d' ':

copy_max_length_text(number_buf,field,field_length);

* va_arg(var_argument,unsigned long *)=

strtoul(number_buf,NULL ,10);

休息;
Anyway, it is declared and I assume largely defined the same
way sscanf() is:

int scan_line(char *line,char *format,...) {
va_list var_argument;

/* loop to match up format string with argument list and assign to
pointers */
}

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;



我会反对这个建议。大多数人都希望''d''代表$

而不是无符号长。你会得到你现在看到的同样问题

float如果这个代码进入一个int和long不同的系统

sizes。

I''d advice against this. Most people will expect ''d'' to be for int
not unsigned long. You will get the same problem you now see with
float if this code gets to a system where ints and longs are different
sizes.


case''f'':

copy_max_length_text(number_buf,field,field_length);

* va_arg(var_argument,double *)= strtod (number_buf,NULL);

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



< snip>

<snip>


...


" case''f''"被分配为0.0000 ...如果参数实际上将

指向一个浮点数,但可以正常分配给一个双精度数。可能会有一些东西

这里我很想丢失,但是因为var_arg()的默认促销,<

变量参数列表,我感到很困惑,

但是我不确定这里的问题是什么...
...

"case ''f''" is assigned as 0.0000... if the argument actually points
to a float, but works OK assigned to a double. There may be something
simple I''m missing here, but I get confused enough working with
variable argument list, because of the default promotions of var_arg(),
but I''m not sure that is even the issue here...



问题是你不能谎言"使用va_arg。如果指针是指向浮点数的
指针,则必须将参数转换为浮点指针。

假装,正如您的代码所做的那样,它指向的是<可能是不同大小的
将无法正常工作。


与写作相同:


float f ;

double * dp =(double *)& f;

* dp = 42;

The issue is that you can''t "lie" using va_arg. If the pointer is
pointer to a float, you must convert the argument to a float pointer.
pretending, as your code does, that it points to something that is
probably of a different size will just not work.

It is the same as writing:

float f;
double *dp = (double *)&f;
*dp = 42;


我认为必须有可能做到这一点,因为sscanf()

做对了,但就像我说我可能错过了很多东西

简单...
I''m assuming it must be possible to do this right, since sscanf()
does it right, but like I say I''m probably missing something very
simple...



Scanf有长度修饰符所以%f期望浮动*,但是%lf期望

a倍*(%Lf是长双倍*)。


-

Ben。

Scanf has "length modifiers" so %f expects a float *, but %lf expects
a double * (%Lf is for long double *).

--
Ben.


2008年7月12日星期六21:17:54 GMT,Bill Reid

< ho ********@happyhealthy.netwrote:
On Sat, 12 Jul 2008 21:17:54 GMT, "Bill Reid"
<ho********@happyhealthy.netwrote:

>
我刚注意到我的改进了如果指定给的变量被声明为浮动,则sscanf()的版本不会正确分配浮点数。而不是双重。 (这从来没有出现过,因为我很少使用浮动来做任何事情,并且几乎没有使用该功能的第一个浮点数;我只是在乱搞/>对所有情况进行测试并发现问题。)
>
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.)



[...]

[...]


>
问题是当我到达为指针实际分配
值的时候:


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;
>
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实际上对待%d作为有符号整数。如果你想长期使用

,你可能想要%ld代替。

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


>

case''f'':

copy_max_length_text(number_buf,field,field_length);

* va_arg(var_argument,double *)= strtod(number_buf,NULL);

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



在这种情况下,sscanf使用%f表示浮点数而不是双精度数。如果你想要它的工作方式与scanf完全相同,则将double *更改为float *,并将

添加为%lf的处理。


一般情况下,你需要为''l'添加一个大小写,并设置一个标志,表示你正在处理long / double而不是int / float。

。如果

你没有处理这个标志,你就不会得到预期的

结果。

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.

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.

这篇关于关于铸造double to float的真实专家的问题......的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆