0

このメソッドは、特定の小数に収まる最大の 2 の累乗を見つけるために作成しました。数値ストレージでの入力オーバーフロー エラーを回避するために、10 進数は char 配列形式になっています。2 の累乗は、float の pow(2, power) 形式で計算されます。8.000000 次に、この数値をメソッドに送信して、ピリオドと末尾の 0 を削除します。すなわち。8.000000 は 8 になります

1  #include <string.h>
2  #include <stdio.h>
3  #include <stdlib.h>
4  #include <memory.h>
5  #include <math.h>
6
7   int i;
16
17  void removeFloatZeros(char *floatvalue)
18  {
19      char *ptr = strchr(floatvalue, '.');
20      *ptr = '\0';
21  }
22
45
173 char *decimalToBinary(char *decimal)
174 {
176     int x;
177     double power = 0;
178     char *binary = malloc(sizeof(char *) * 1024);
179     char *twosPower = malloc(sizeof(char *) * 1024);
180
181     /* What is the greatest power of 2 that will fit into the decimal? */
182     for(x = 0; x <= 30; x++)
183     {
184         power = pow(2.0, x);
185         snprintf(twosPower, 1023, "%f", power);
186         removeFloatZeros(twosPower);
189         printf("strcmp(decimal, twosPower) = %d\n", strcmp(twosPower, decimal));  
190         memset(twosPower, '\0', 1023);
191     }
214 }
215
216 int main(int argc, char*argv[])
217 {
218     char *dec1 = argv[1];
219     decimalToBinary(dec1);
220     return 1;
221 }
222

たとえば、argv[1] に 20 を入力すると、次のように出力されます。

strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = -1  
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = 1
strcmp(decimal, twosPower) = -1

これのどこが間違っているのですか?また、for ループの終了条件を無視します。6 回目の反復の前にすべて 1 を出力し、6 回目と 6 回目の反復後にすべて -1 を出力することになっています。

4

2 に答える 2

2

strcmpの戻り値:

ゼロ値は、両方の文字列が等しいことを示します。

ゼロより大きい値は、一致しない最初の文字の値がstr2よりもstr1の方が大きいことを示します。

また、ゼロ未満の値はその逆を示します。

入力:20ループの最初の反復:twosPower = "1" strcmp( "20"、 "1")

最初の文字が一致せず、str2( "1")の値がstr1( "2")よりも小さい->負の値を返します。

残りの反復はそれ自体を説明する必要があります...

また、編集:

printf("strcmp(decimal, twosPower) = %d\n", strcmp(twosPower, decimal)); 

printf形式の文字列は、パラメータで実行していることとは逆のことを示しています。

編集:

str1    str2    
1       20  First char that differs is '1' vs. '2'. '1' (ASCII 49) is smaller than '2' (ASCII 50), 49 - 50 = -1 = return value
2       20  First char that differs is '\0' vs. '0'. '\0' (ASCII 0) is smaller than '0' (ASCII 48), 0 - 48 = -48 = return value
4       20  First char that differs is '4' vs. '2'. '4' (ASCII 52) is greather than '2' (ASCII 50), 52 - 50 = 2 = return value
8       20  First char that differs is '8' vs. '2'. '4' (ASCII 56) is greather than '2' (ASCII 50), 56 - 50 = 6 = return value
16      20  First char that differs is '1' vs. '2'. '1' (ASCII 49) is smaller than '2' (ASCII 50), 49 - 50 = -1 = return value

... and so on ...

たぶん、この出力はもう少し役立ちます

さらに、strcmpの戻り値は、異なる最初の文字に依存しているため、数値の2の最大の累乗を見つける方法には欠陥があります。したがって、strcmp( "2"、 "16")とstrcmp( "200000000"、 "16")は常に同じものを返します。

于 2012-02-18T03:39:56.577 に答える
1

コードのこのクリーンアップされたバージョンは、次の出力を生成します。

$ ./xx 20
strcmp(1, 20) = -1
strcmp(2, 20) = -48
strcmp(4, 20) = 2
strcmp(8, 20) = 6
strcmp(16, 20) = -1
strcmp(32, 20) = 1
strcmp(64, 20) = 4
strcmp(128, 20) = -1
strcmp(256, 20) = 5
strcmp(512, 20) = 3
strcmp(1024, 20) = -1
strcmp(2048, 20) = 52
strcmp(4096, 20) = 2
strcmp(8192, 20) = 6
strcmp(16384, 20) = -1
strcmp(32768, 20) = 1
strcmp(65536, 20) = 4
strcmp(131072, 20) = -1
strcmp(262144, 20) = 6
strcmp(524288, 20) = 3
strcmp(1048576, 20) = -1
strcmp(2097152, 20) = 57
strcmp(4194304, 20) = 2
strcmp(8388608, 20) = 6
strcmp(16777216, 20) = -1
strcmp(33554432, 20) = 1
strcmp(67108864, 20) = 4
strcmp(134217728, 20) = -1
strcmp(268435456, 20) = 6
strcmp(536870912, 20) = 3
strcmp(1073741824, 20) = -1
$

小さな変化がたくさんあると言って十分です。

#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

static void removeFloatZeros(char *floatvalue)
{
    char *ptr = strchr(floatvalue, '.');
    *ptr = '\0';
}

static void decimalToBinary(char *decimal)
{
    int x;
    double power = 0;
    char *twosPower = malloc(sizeof(char *) * 1024);

    /* What is the greatest power of 2 that will fit into the decimal? */
    for(x = 0; x <= 30; x++)
    {
        power = pow(2.0, x);
        snprintf(twosPower, 1023, "%f", power);
        removeFloatZeros(twosPower);
        printf("strcmp(%s, %s) = %d\n", twosPower, decimal, strcmp(twosPower, decimal));  
        //printf("strcmp(decimal, twosPower) = %d\n", strcmp(twosPower, decimal));  
        memset(twosPower, '\0', 1023);
    }
    free(twosPower);
}

int main(int argc, char*argv[])
{
    for (int i = 1; i < argc; i++)
        decimalToBinary(argv[i]);
    return 0;
}

比較した値を表示すると、物事が理解しやすくなります。メモリを解放する (または自動配列を使用する) 必要があります。ヘッダーを使用する必要があります。static宣言は 100% 必要というわけではありませんが、非常に面倒なコンパイラ設定でコンパイルしても警告が表示されないことを意味します。

しかし、重要な変更点は、比較されている値を出力することですstrcmp()

(比較を行う前に、先頭に適切な数のゼロを追加することを検討してください。)

于 2012-02-18T03:47:28.373 に答える