1

以下の私の C コードで奇妙なことが起こっています。

数値を比較したいので、小数点以下 4 桁に丸めます。

デバッグしたところ、渡されたデータを確認できました。

の値tmp_ptr->current_longitudeは 6722.31500000 で、 の値tmp_ptr->current_latitudeは 930.0876500000 です。

sprintf ステートメントを使用した後:

charTmpPtrXPos = "6722.3150" and charTmpPtrYPos = "930.0876".

speed_info->myXPos と speed_info->myYPos に対してまったく同じ結果が期待されますが、奇妙なことに、 sprintf ステートメントspeed_info->myXPos = 6722.31500000の値speed_info->myYPos > = 30.0876500000

charSpeedPtrYPos= "930.0877"

したがって、基本的に sprintf ステートメントは 2 番目の値に対して異なる動作をし、それを切り上げているように見えます。これをデバッグしたところ、sprintf ステートメントへの入力がまったく同じであることがわかりました。

誰かがこれの理由を考えることができますか?

sizeOfSpeedList = op_prg_list_size (global_speed_trajectory);

tmp_ptr= (WsqT_Location_Message*)op_prg_mem_alloc(sizeof(WsqT_Location_Message));
tmp_ptr = mbls_convert_lat_long_to_xy (own_node_objid);

sprintf(charTmpPtrXPos, "%0.4lf", tmp_ptr->current_longitude);
sprintf(charTmpPtrYPos, "%0.4lf", tmp_ptr->current_latitude);

speed_info = (SpeedInformation *) op_prg_mem_alloc (sizeof (SpeedInformation));
for (count=0; count<sizeOfSpeedList; count++)
{
    speed_info = (SpeedInformation*) op_prg_list_access (global_speed_trajectory, count);

    sprintf(charSpeedPtrXPos, "%0.4lf", speed_info->myXPos);
    sprintf(charSpeedPtrYPos, "%0.4lf", speed_info->myYPos);

    //if((tmp_ptr->current_longitude == speed_info->myXPos) && (tmp_ptr->current_latitude == speed_info->myYPos))
    if ((strcmp(charTmpPtrXPos, charSpeedPtrXPos) == 0) && (strcmp(charTmpPtrYPos, charSpeedPtrYPos) == 0))
    {
        my_speed = speed_info->speed;
        break;
    }
}
4

3 に答える 3

2

floataと aの違いdoubleです。

OP はtmp_ptr->current_latitudeとしてfloatおよびspeed_info->myYPosとして使用している可能性がありdoubleます。doubleスペース/速度が の使用を義務付けない限り、OP の使用を提案しますfloat

int main() {
  float  f1 = 930.08765;
  double d1 = 930.08765;
  printf("float  %0.4f\ndouble %0.4f\n", f1, d1);
  return 0;
}

float  930.0876  
double 930.0877

通常floatは IEEE 4 バイト 2 進浮動小数点表現を使用するf1ため、正確な値は
930.087646484375
930.0876 になります (これは 4 桁の出力結果です) 。
これは 930.08765 に最も近いfloat値です。

同様に、 の場合、 は 930.0876500000000532963895238935947418212890625 930.0877の正確な値をdouble取り ます (これは 4 桁の出力結果です) d1

一般に、小数点以下の桁数を増やして、他の数値でこれが発生する可能性を減らすことはできますが、それをなくすことはできません


クイックフィックス候補

sprintf(charSpeedPtrYPos, "%0.4lf", (float) speed_info->myYPos);

speed_info->myYPosこれにより、最初に値が からに変換されますfloat。タイプの非プロトタイプ パラメータはに渡される前に にfloat変換されるため、値は に変換されて戻されます。最終的な結果として、数値の精度が失われますが、同じ文字列変換が行われます。doublesprintf()double

printf("(float) double  %0.4f\n", (float) d1);
// (float) double  930.0876

ところで: lin"%0.4lf"はコード生成の目的を果たしません。でも許される。

于 2013-08-09T14:52:09.557 に答える