2014-01-21 4 views
0

Этот код иллюстрирует проблему гораздо проще (извините за предыдущий, это слишком сложно). В любом случае, обратите внимание, что out_b будет правильно распечатываться для любых значений индекса от 0 до 958. Однако переменная out_a всегда будет распечатывать 36893488147419103232. И они оба типа DOUBLE. Похоже, операция «+» испортила тип out_a. Он не будет работать, даже если приложение имеет тип DOUBLE.Не может показаться, что здесь происходит

#include <stdio.h> 
#include <stdlib.h> 
#include <gsl/gsl_math.h> 
#include <string.h> 

double main (int argc, char *argv[]) { 

    char *wrapper = "11111111111111111111111111111111111111111111111111111111111111111"; // 65 digits 
    int appendix = atoi(argv[1]); 

    int length = strlen(wrapper); 

    double out_a = gsl_pow_int(2,length) + appendix; 
    double out_b = gsl_pow_int(2,length + appendix); 

    printf("%.0lf %.0lf\n", out_a, out_b); 
} 

Оригинальный вопрос программы

Это C бы вычислить десятичный эквивалент в любой двоичный вход, до тех пор, как это меньше, чем 64 цифр ... Я не понимаю, почему. Любая помощь оценивается.

#include <stdio.h> 
#include <stdlib.h> 
#include <gsl/gsl_math.h> 
#include <string.h> 

long double main (int argc, char *argv[]) { 

    char *wrapper = argv[1]; 

    static int *array, length, llo, i; 
    static long double sum; 

    while (*wrapper && (*wrapper == '0')) wrapper++; 

    length = strlen(wrapper); 
    llo = length - 1; 

    array = malloc((length*sizeof(*array))+1); 

    for (i = 0; i < length; i++) { 
     if (wrapper[i] >= '0' && wrapper[i] <= '1') { 
      array[i] = wrapper[llo-i] - 48; 
      sum += array[i] * gsl_pow_int(2,i); 
     } 

     else printf("Some error.\n"); 
    } 

    free(array); 

    printf("%.0Lf\n", sum); 

} 
+2

Есть ли определенный раздел программы, о котором вы задавали вопрос? –

+1

Вы пробовали переходить через код, по очереди, в отладчик? –

+0

Может ли 2, поднятый к власти 64, храниться в целочисленной переменной? Я не уверен в этом. – Dinesh

ответ

1

Общий код нормально, но:

  1. Возврат тип магистральный должен быть ИНТ
  2. Не действительно нужно array
  3. Должно быть if (wrapper[llo-i] >= '0' && wrapper[llo-i] <= '1') {
  4. Initialze sum до 0

См.: http://ideone.com/2ECduk

0

Что касается вашего вопроса: Я не понимаю почему. Любая помощь оценивается.

Двоичное представление целого числа показан в виде последовательности 1 и 0, каждый из последовательно с более высокой мощностью, равной 2.

например: 10010 равна:

1  0  0  1  0  

(1 * (2^4)) + (0 * (2^3)) + (0 * (2^2)) + (1 * (2^1)) + (0 * (2^0))
или: 16 + 0 + 0 + 2 + 0 или: 18

Раздел кода здесь: (из вашего примера выше)

for (i = 0; i < length; i++) {//for each character in input (argv[1]) 
    if (wrapper[llo-i] >= '0' && wrapper[llo-i] <= '1') {//test input for 1 or 0 (note llo-i correction) 
     array[i] = wrapper[llo-i] - 48;//get next value into int array (note 48 is ascii value for 0) 
             //results in placing either 1 or 0 into array[i] 
     sum += array[i] * gsl_pow_int(2,i); //perform multiplication of appropriate power of 2 and add to sum 
    } 

    else printf("Some error.\n"); 
} 

Просто делает то же самое. См. Комментарии, чтобы объяснить, как.

+0

Спасибо, но я понимаю этот бит. Моя проблема заключается в том, чтобы выяснить, почему входные данные, превышающие 64 бита, будут терпеть неудачу, поскольку переменная суммы может хранить предполагаемый результат. –

+0

Возможно, это *** [сообщение] (http://stackoverflow.com/questions/15601430/storing-and-printing-integer-values-greater-than-264) *** ответит на ваши вопросы. Пожалуйста, будьте более конкретными в формулировании ваших вопросов. – ryyker

0

GSL man page для gsl_pow_int явно указан, что эта функция используется для вычисления небольших целых степеней эффективно, путем вычисления таких вещей, как x^8 как ((x^2)^2)^2). Несмотря на то, что он возвращает двойной, он не имеет неограниченной точности.

EDIT

Честно говоря, этот код является чрезмерно сложным, делает некоторые ненужные управления памятью, и вызывает неопределенное поведение, по крайней мере в одном отношении.Сделай мне одолжение и посмотреть, если следующий код не дает вам результаты вы ожидаете:

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

int main(int argc, char **argv) 
{ 
    if (argc < 2) 
    { 
    printf("USAGE: %s binary-string\n", argv[0]); 
    exit(0); 
    } 

    long double result = 0; 
    char *p = argv[1]; 

    while (*p == '0' || *p == '1') 
    { 
    result *= 2; 
    result += *p++ - '0'; 
    } 

    if (*p && *p != '0' && *p != '1') 
    { 
    printf("%s is not a valid binary string; " 
      "found non-binary digit %c at position %zu\n", 
     argv[1], *p, (p - argv[1]) + 1); 
    } 
    else 
    { 
    printf("Result: %Lf\n", result); 
    } 

    return 0; 
} 

EDIT

Вот результаты по моей системе дома, до 127 бит; Я не вижу явного разрыва:

[email protected]:~/Development/Prototypes/C/converter$ input=1; let len=$(echo $input | wc -c)-1; while [ $len -lt 128 ]; do echo "$input ($len)"; ./converter $input; input=$input"0"; let len=$(echo $input | wc -c)-1; done 
1 (1) 
Result: 1.000000 
10 (2) 
Result: 2.000000 
100 (3) 
Result: 4.000000 
1000 (4) 
Result: 8.000000 
10000 (5) 
Result: 16.000000 
100000 (6) 
Result: 32.000000 
1000000 (7) 
Result: 64.000000 
10000000 (8) 
Result: 128.000000 
100000000 (9) 
Result: 256.000000 
1000000000 (10) 
Result: 512.000000 
10000000000 (11) 
Result: 1024.000000 
100000000000 (12) 
Result: 2048.000000 
1000000000000 (13) 
Result: 4096.000000 
10000000000000 (14) 
Result: 8192.000000 
100000000000000 (15) 
Result: 16384.000000 
1000000000000000 (16) 
Result: 32768.000000 
10000000000000000 (17) 
Result: 65536.000000 
100000000000000000 (18) 
Result: 131072.000000 
1000000000000000000 (19) 
Result: 262144.000000 
10000000000000000000 (20) 
Result: 524288.000000 
100000000000000000000 (21) 
Result: 1048576.000000 
1000000000000000000000 (22) 
Result: 2097152.000000 
10000000000000000000000 (23) 
Result: 4194304.000000 
100000000000000000000000 (24) 
Result: 8388608.000000 
1000000000000000000000000 (25) 
Result: 16777216.000000 
10000000000000000000000000 (26) 
Result: 33554432.000000 
100000000000000000000000000 (27) 
Result: 67108864.000000 
1000000000000000000000000000 (28) 
Result: 134217728.000000 
10000000000000000000000000000 (29) 
Result: 268435456.000000 
100000000000000000000000000000 (30) 
Result: 536870912.000000 
1000000000000000000000000000000 (31) 
Result: 1073741824.000000 
10000000000000000000000000000000 (32) 
Result: 2147483648.000000 
100000000000000000000000000000000 (33) 
Result: 4294967296.000000 
1000000000000000000000000000000000 (34) 
Result: 8589934592.000000 
10000000000000000000000000000000000 (35) 
Result: 17179869184.000000 
100000000000000000000000000000000000 (36) 
Result: 34359738368.000000 
1000000000000000000000000000000000000 (37) 
Result: 68719476736.000000 
10000000000000000000000000000000000000 (38) 
Result: 137438953472.000000 
100000000000000000000000000000000000000 (39) 
Result: 274877906944.000000 
1000000000000000000000000000000000000000 (40) 
Result: 549755813888.000000 
10000000000000000000000000000000000000000 (41) 
Result: 1099511627776.000000 
100000000000000000000000000000000000000000 (42) 
Result: 2199023255552.000000 
1000000000000000000000000000000000000000000 (43) 
Result: 4398046511104.000000 
10000000000000000000000000000000000000000000 (44) 
Result: 8796093022208.000000 
100000000000000000000000000000000000000000000 (45) 
Result: 17592186044416.000000 
1000000000000000000000000000000000000000000000 (46) 
Result: 35184372088832.000000 
10000000000000000000000000000000000000000000000 (47) 
Result: 70368744177664.000000 
100000000000000000000000000000000000000000000000 (48) 
Result: 140737488355328.000000 
1000000000000000000000000000000000000000000000000 (49) 
Result: 281474976710656.000000 
10000000000000000000000000000000000000000000000000 (50) 
Result: 562949953421312.000000 
100000000000000000000000000000000000000000000000000 (51) 
Result: 1125899906842624.000000 
1000000000000000000000000000000000000000000000000000 (52) 
Result: 2251799813685248.000000 
10000000000000000000000000000000000000000000000000000 (53) 
Result: 4503599627370496.000000 
100000000000000000000000000000000000000000000000000000 (54) 
Result: 9007199254740992.000000 
1000000000000000000000000000000000000000000000000000000 (55) 
Result: 18014398509481984.000000 
10000000000000000000000000000000000000000000000000000000 (56) 
Result: 36028797018963968.000000 
100000000000000000000000000000000000000000000000000000000 (57) 
Result: 72057594037927936.000000 
1000000000000000000000000000000000000000000000000000000000 (58) 
Result: 144115188075855872.000000 
10000000000000000000000000000000000000000000000000000000000 (59) 
Result: 288230376151711744.000000 
100000000000000000000000000000000000000000000000000000000000 (60) 
Result: 576460752303423488.000000 
1000000000000000000000000000000000000000000000000000000000000 (61) 
Result: 1152921504606846976.000000 
10000000000000000000000000000000000000000000000000000000000000 (62) 
Result: 2305843009213693952.000000 
100000000000000000000000000000000000000000000000000000000000000 (63) 
Result: 4611686018427387904.000000 
1000000000000000000000000000000000000000000000000000000000000000 (64) 
Result: 9223372036854775808.000000 
10000000000000000000000000000000000000000000000000000000000000000 (65) 
Result: 18446744073709551616.000000 
100000000000000000000000000000000000000000000000000000000000000000 (66) 
Result: 36893488147419103232.000000 
1000000000000000000000000000000000000000000000000000000000000000000 (67) 
Result: 73786976294838206464.000000 
10000000000000000000000000000000000000000000000000000000000000000000 (68) 
Result: 147573952589676412928.000000 
100000000000000000000000000000000000000000000000000000000000000000000 (69) 
Result: 295147905179352825856.000000 
1000000000000000000000000000000000000000000000000000000000000000000000 (70) 
Result: 590295810358705651712.000000 
10000000000000000000000000000000000000000000000000000000000000000000000 (71) 
Result: 1180591620717411303424.000000 
100000000000000000000000000000000000000000000000000000000000000000000000 (72) 
Result: 2361183241434822606848.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000 (73) 
Result: 4722366482869645213696.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000 (74) 
Result: 9444732965739290427392.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000 (75) 
Result: 18889465931478580854784.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000 (76) 
Result: 37778931862957161709568.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000 (77) 
Result: 75557863725914323419136.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000 (78) 
Result: 151115727451828646838272.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000 (79) 
Result: 302231454903657293676544.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000 (80) 
Result: 604462909807314587353088.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000 (81) 
Result: 1208925819614629174706176.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000 (82) 
Result: 2417851639229258349412352.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000 (83) 
Result: 4835703278458516698824704.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000 (84) 
Result: 9671406556917033397649408.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (85) 
Result: 19342813113834066795298816.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (86) 
Result: 38685626227668133590597632.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (87) 
Result: 77371252455336267181195264.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (88) 
Result: 154742504910672534362390528.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (89) 
Result: 309485009821345068724781056.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (90) 
Result: 618970019642690137449562112.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (91) 
Result: 1237940039285380274899124224.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (92) 
Result: 2475880078570760549798248448.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (93) 
Result: 4951760157141521099596496896.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (94) 
Result: 9903520314283042199192993792.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (95) 
Result: 19807040628566084398385987584.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (96) 
Result: 39614081257132168796771975168.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (97) 
Result: 79228162514264337593543950336.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (98) 
Result: 158456325028528675187087900672.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (99) 
Result: 316912650057057350374175801344.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (100) 
Result: 633825300114114700748351602688.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (101) 
Result: 1267650600228229401496703205376.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (102) 
Result: 2535301200456458802993406410752.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (103) 
Result: 5070602400912917605986812821504.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (104) 
Result: 10141204801825835211973625643008.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (105) 
Result: 20282409603651670423947251286016.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (106) 
Result: 40564819207303340847894502572032.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (107) 
Result: 81129638414606681695789005144064.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (108) 
Result: 162259276829213363391578010288128.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (109) 
Result: 324518553658426726783156020576256.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (110) 
Result: 649037107316853453566312041152512.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (111) 
Result: 1298074214633706907132624082305024.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (112) 
Result: 2596148429267413814265248164610048.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (113) 
Result: 5192296858534827628530496329220096.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (114) 
Result: 10384593717069655257060992658440192.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (115) 
Result: 20769187434139310514121985316880384.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (116) 
Result: 41538374868278621028243970633760768.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (117) 
Result: 83076749736557242056487941267521536.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (118) 
Result: 166153499473114484112975882535043072.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (119) 
Result: 332306998946228968225951765070086144.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (120) 
Result: 664613997892457936451903530140172288.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (121) 
Result: 1329227995784915872903807060280344576.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (122) 
Result: 2658455991569831745807614120560689152.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (123) 
Result: 5316911983139663491615228241121378304.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (124) 
Result: 10633823966279326983230456482242756608.000000 
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (125) 
Result: 21267647932558653966460912964485513216.000000 
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (126) 
Result: 42535295865117307932921825928971026432.000000 
1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (127) 
Result: 85070591730234615865843651857942052864.000000 
+0

Нет, это не причина. Функция работает отлично, до 2^1023. –

+0

@EdwardTigert: см. Мое редактирование. У вашего кода есть некоторые проблемы, и они могут нести ответственность за ваши проблемы. –

+0

он ведет себя точно так же, как и мой. Попробуйте ввести любые двоичные файлы длиной более 64 цифр, и вы увидите. –

Смежные вопросы