Форум программистов, компьютерный форум CyberForum.ru

Странный тип Double - C++

Восстановить пароль Регистрация
 
bgm123
39 / 39 / 16
Регистрация: 29.01.2013
Сообщений: 277
08.04.2014, 20:17     Странный тип Double #1
В функции main вводится hex-строка. Затем подсчитывается частота символов в этой строке и то (GetFreqChars). Затем вычисляется насколько полученные результаты соответствуют частотам StFreqDistr (GetFreqDif). После этого выводится результат: первая строка соответствует больше чем вторая или нет. Почему-то, если в функции GetFreqChars убрать строку где умножение на 1000, то результат меняется на противоположный. Почему так происходит?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
const double StFreqDistr[SizeEnglishAlpha] = {
    8.167, 1.492, 2.782, 4.253, 12.702, 2.228, 2.015, 6.094, 6.966,
    0.153, 0.772, 4.025, 2.406, 6.749, 7.507, 1.929, 0.095, 5.987, 
    6.327, 9.056, 2.758, 0.978, 2.360, 0.150, 1.974, 0.074
};
 
struct Symbols{
    UCHAR key;
    double value;
};
 
//подсчет частоты символов в строке
void GetFreqChars(double *result, UCHAR_C *text, UINT length_text)
{
    UINT i, count_letters;
 
    memset(result, 0, SizeEnglishAlpha * sizeof(double));
    for (count_letters = i = 0; i < length_text; i++){
        if (isalpha(text[i])){
            result[tolower(text[i]) - 'a']++;
            count_letters++;
        }
    }
    
    for (i = 0; i < SizeEnglishAlpha; i++){
        result[i] *= 1000; //если это убрать, то результат меняется
        result[i] /= (double)count_letters;
    }
}
 
//сравнение структур
int CompareKeys(const void *k, const void *k2)
{
    Symbols *key = (Symbols *)k;
    Symbols *key2 = (Symbols *)k2;
 
    if (key->value < key2->value) return -1;
    else if (key->value > key2->value) return 1;
    else return 0;
}
 
//разница в частотах
double GetFreqDif(const double *f)
{
    double diff = 0.0;
 
    for (UINT i = 0; i < SizeEnglishAlpha; i++)
        diff += abs(f[i] - StFreqDistr[i]);
 
    return diff;
}
 
 
void XorRepeatKey(UCHAR *result, UCHAR_C *text, UINT size_text, UCHAR_C *key, UINT size_key)
{
    for (UINT i = 0, j = 0; i < size_text; i++, j = ++j % size_key)
        result[i] = text[i] ^ key[j];
}
 
//xor со строкой
void XorByOneChar(UCHAR *result, UCHAR key, UCHAR_C *text, UINT size_text)
{
    XorRepeatKey(result, text, size_text, &key, 1);
}
 
int HexRead(UCHAR *dest)
{
    UCHAR temp[SIZE_INPUT_MAX + 1];
    UINT length, i, j;
 
    std::cin.get((char *)temp, SIZE_INPUT_MAX + 1);
    length = strlen((char *)temp);
 
    if (length % 2) return ERR_ODD_LENGTH;
    else if (getchar() != '\n') return ERR_MANY_VALUES;
    else if (!CharToHex(temp, length)) return ERR_ILLEGAL_SYMBOL;
 
    for (j = i = 0; i < length; i += 2, j++)
        dest[j] = (temp[i] << 4) + temp[i + 1];
 
    return length / 2;
}
 
int main(){
    UCHAR a[SIZE_INPUT_MAX];
    UCHAR b[SIZE_INPUT_MAX];
    UCHAR r[SIZE_INPUT_MAX];
    UINT la, lb, lr;
    double freqb[26];
    double freqr[26];
    double bd, rd;
 
    cout << "enter string: ";
    la = HexRead(a); 
    
    XorByOneChar(b, 'n', a, la);
    XorByOneChar(r, 'm', a, la);
    GetFreqChars(freqb, b, la);
    GetFreqChars(freqr, r, la);
    bd = GetFreqDif(freqb);
    rd = GetFreqDif(freqr);
    
    cout << boolalpha << (bd < rd) << endl;
 
    return 0;
}
Добавлено через 10 минут
Причем, если в функции main после всех вычисления сделать сравнения:
C++
1
bd < rd
и
C++
1
 bd * 1000 < rd * 1000
то результат будет одинаковым.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.04.2014, 20:17     Странный тип Double
Посмотрите здесь:

C++ Точность.Тип double
C++ Ошибка: error LNK2001: unresolved external symbol "double __cdecl Akk(double,double,double)"
C++ Тип double, ввод
C++ Difftime() должен возвращать тип double
Как сконвертировать свой тип в тип double? C++
C++ Вычислить выражение, используя тип double
Не могу преобразовать тип char в тип double C++
C++ Тип double в условном выражении

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

Текущее время: 17:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru