Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/18: Рейтинг темы: голосов - 18, средняя оценка - 4.89
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 491

Конвертация IBM float в IEEE float

25.01.2020, 20:11. Показов 3869. Ответов 14
Метки ibm, ieee (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день,

Мне необходимо конвертировать IBM float в IEEE float. По этой ссылке http://support.sas.com/techsup/technote/ts140.pdf имеется код, реализующий данный функционал (начиная со страницы 8 и до конца).
Я скопировал этот код в файлы testieee.c и ieee.c. Но так как я новичок в этом деле, не могу понять как мне запустить проект с этими файлами, если они формата , а не заголовочные .h?
Я использую Qt 5.14.0, MSVC 2017 x64, Windows 10. Проект состоит из пустого файла main.cpp, testieee.c и ieee.c и .pro файл

Добавлено через 4 часа 23 минуты
подскажите, пожалуйста, вот переписанный ieee.c файл, который должен реализовать конвертирование из IBM to IEEE и наоборот:
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
#define CN_TYPE_NATIVE 0
#define CN_TYPE_XPORT 1
#define CN_TYPE_IEEEB 2
#define CN_TYPE_IEEEL 3
int cnxptiee(char *from, int fromtype,char *to, int totype);
void xpt2ieee(unsigned char *xport, unsigned char *ieee);
void ieee2xpt(unsigned char *ieee, unsigned char *xport);
#ifndef FLOATREP
    #define FLOATREP get_native()
    int get_native(void);
#endif
 
/*-------------------------------------------------------------------*/
/* rc = cnxptiee(from,fromtype,to,totype); */
/* */
/* where */
/* */
/* from pointer to a floating point value */
/* fromtype type of floating point value (see below) */
/* to pointer to target area */
/* totype type of target value (see below) */
/* */
/* floating point types: */
/* 0 native floating point */
/* 1 IBM mainframe (transport representation) */
/* 2 Big endian IEEE floating point */
/* 3 Little endian IEEE floating point */
/* */
/* rc = cnxptiee(from,0,to,1); native -> transport */
/* rc = cnxptiee(from,0,to,2); native -> Big endian IEEE */
/* rc = cnxptiee(from,0,to,3); native -> Little endian IEEE */
/* rc = cnxptiee(from,1,to,0); transport -> native */
/* rc = cnxptiee(from,1,to,2); transport -> Big endian IEEE */
/* rc = cnxptiee(from,1,to,3); transport -> Little endian IEEE */
/* rc = cnxptiee(from,2,to,0); Big endian IEEE -> native */
/* rc = cnxptiee(from,2,to,1); Big endian IEEE -> transport */
/* rc = cnxptiee(from,2,to,3); Big endian IEEE -> Little endian IEEE */
/* rc = cnxptiee(from,3,to,0); Little endian IEEE -> native */
/* rc = cnxptiee(from,3,to,1); Little endian IEEE -> transport */
/* rc = cnxptiee(from,3,to,2); Little endian IEEE -> Big endian IEEE */
/*-------------------------------------------------------------------*/
int cnxptiee(char *from, int fromtype, char *to, int totype){
    char temp[8];
    int i;
    if (fromtype == CN_TYPE_NATIVE) {
        fromtype = FLOATREP;
    }
    switch(fromtype) {
        case CN_TYPE_IEEEL :
        if (totype == CN_TYPE_IEEEL)
            break;
        for (i=7;i>=0;i--) {
            temp[7-i] = from[i];
        }
        from = temp;
        fromtype = CN_TYPE_IEEEB;
        /* break intentionally omitted */
        case CN_TYPE_IEEEB :
        /* break intentionally omitted */
        case CN_TYPE_XPORT :
        break;
        default:
        return(-1);
    }
    if (totype == CN_TYPE_NATIVE) {
        totype = FLOATREP;
    }
    switch(totype) {
        case CN_TYPE_XPORT :
        case CN_TYPE_IEEEB :
        case CN_TYPE_IEEEL :
        break;
        default:
        return(-2);
    }
    if (fromtype == totype) {
        memcpy(to,from,8);
        return(0);
    }
    switch(fromtype) {
        case CN_TYPE_IEEEB :
        if (totype == CN_TYPE_XPORT)
            ieee2xpt(from,to);
        else memcpy(to,from,8);
            break;
        case CN_TYPE_XPORT :
        xpt2ieee(from,to);
            break;
    }
    if (totype == CN_TYPE_IEEEL) {
        memcpy(temp,to,8);
        for (i=7;i>=0;i--) {
            to[7-i] = temp[i];
        }
    }
    return(0);
}
 
int get_native() {
    static char float_reps[][8] = {
        {0x41,0x10,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x3f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f}
    };
    static double one = 1.00;
    int i,j;
    j = sizeof(float_reps)/8;
    for (i=0;i<j;i++) {
        if (memcmp(&one,float_reps+i,8) == 0)
            return(i+1);
    }
    return(-1);
}
 
#ifdef BIG_ENDIAN
    #define REVERSE(a,b)
#endif
#ifdef LITTLE_ENDIAN
    #define DEFINE_REVERSE
    void REVERSE();
#endif
#if !defined(DEFINE_REVERSE) && !defined(REVERSE)
    #define DEFINE_REVERSE
    void REVERSE(char *intp, int l);
#endif
void xpt2ieee(unsigned char *xport, unsigned char *ieee){
    char temp[8];
    register int shift;
    register int nib;
    unsigned long ieee1,ieee2;
    unsigned long xport1 = 0;
    unsigned long xport2 = 0;
    memcpy(temp,xport,8);
    memset(ieee,0,8);
    if (*temp && memcmp(temp+1,ieee,7) == 0) {
        ieee[0] = ieee[1] = 0xff;
        ieee[2] = ~(*temp);
        return;
    }
    memcpy(((char *)&xport1)+sizeof(unsigned long)-4,temp,4);
    REVERSE(&xport1,sizeof(unsigned long));
    memcpy(((char *)&xport2)+sizeof(unsigned long)-4,temp+4,4);
    REVERSE(&xport2,sizeof(unsigned long));
    /***************************************************************/
    /* Translate IBM format floating point numbers into IEEE */
    /* format floating point numbers. */
    /* */
    /* IEEE format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEEEEEMMMM ............ MMMM */
    /* */
    /* Sign bit, 11 bits exponent, 52 bit fraction. Exponent is */
    /* excess 1023. The fraction is multiplied by a power of 2 of */
    /* the actual exponent. Normalized floating point numbers are */
    /* represented with the binary point immediately to the left */
    /* of the fraction with an implied "1" to the left of the */
    /* binary point. */
    /* */
    /* IBM format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEMMMM ......... MMMM */
    /* */
    /* Sign bit, 7 bit exponent, 56 bit fraction. Exponent is */
    /* excess 64. The fraction is multiplied by a power of 16 of */
    /* the actual exponent. Normalized floating point numbers are */
    /* represented with the radix point immediately to the left of*/
    /* the high order hex fraction digit. */
    /* */
    /* How do you translate from IBM format to IEEE? */
    /* */
    /* Translating back to ieee format from ibm is easier than */
    /* going the other way. You lose at most, 3 bits of fraction, */
    /* but nothing can be done about that. The only tricky parts */
    /* are setting up the correct binary exponent from the ibm */
    /* hex exponent, and removing the implicit "1" bit of the ieee*/
    /* fraction (see vzctdbl). We must shift down the high order */
    /* nibble of the ibm fraction until it is 1. This is the */
    /* implicit 1. The bit is then cleared and the exponent */
    /* adjusted by the number of positions shifted. A more */
    /* thorough discussion is in vzctdbl.c. */
    /* Get the first half of the ibm number without the exponent */
    /* into the ieee number */
    ieee1 = xport1 & 0x00ffffff;
    /* get the second half of the ibm number into the second half */
    /* of the ieee number . If both halves were 0. then just */
    /* return since the ieee number is zero. */
    if ((!(ieee2 = xport2)) && !xport1)
        return;
    /* The fraction bit to the left of the binary point in the */
    /* ieee format was set and the number was shifted 0, 1, 2, or */
    /* 3 places. This will tell us how to adjust the ibm exponent */
    /* to be a power of 2 ieee exponent and how to shift the */
    /* fraction bits to restore the correct magnitude. */
    if ((nib = (int)xport1) & 0x00800000)
        shift = 3;
    else if (nib & 0x00400000)
        shift = 2;
    else if (nib & 0x00200000)
        shift = 1;
    else
        shift = 0;
    if (shift){
        /* shift the ieee number down the correct number of places */
        /* then set the second half of the ieee number to be the */
        /* second half of the ibm number shifted appropriately, */
        /* ored with the bits from the first half that would have */
        /* been shifted in if we could shift a double. All we are */
        /* worried about are the low order 3 bits of the first */
        /* half since we're only shifting by 1, 2, or 3. */
        ieee1 >>= shift;
        ieee2 = (xport2 >> shift) |
        ((xport1 & 0x00000007) << (29 + (3 - shift)));
    }
    /* clear the 1 bit to the left of the binary point */
    ieee1 &= 0xffefffff;
    /* set the exponent of the ieee number to be the actual */
    /* exponent plus the shift count + 1023. Or this into the */
    /* first half of the ieee number. The ibm exponent is excess */
    /* 64 but is adjusted by 65 since during conversion to ibm */
    /* format the exponent is incremented by 1 and the fraction */
    /* bits left 4 positions to the right of the radix point. */
    ieee1 |= (((((long)(*temp & 0x7f) - 65) << 2) + shift + 1023) << 20) | (xport1 & 0x80000000);
    REVERSE(&ieee1,sizeof(unsigned long));
    memcpy(ieee,((char *)&ieee1)+sizeof(unsigned long)-4,4);
    REVERSE(&ieee2,sizeof(unsigned long));
    memcpy(ieee+4,((char *)&ieee2)+sizeof(unsigned long)-4,4);
    return;
}
/*-------------------------------------------------------------*/
/* Name: ieee2xpt */
/* Purpose: converts IEEE to transport */
/* Usage: rc = ieee2xpt(to_ieee,p_data); */
/* Notes: this routine is an adaptation of the wzctdbl routine */
/* from the Apollo. */
/*-------------------------------------------------------------*/
 
 
void ieee2xpt(unsigned char *ieee, unsigned char *xport) /* ieee ptr to IEEE field (2-8 bytes) */ /* xport ptr to xport format (8 bytes) */
{
    register int shift;
    unsigned char misschar;
    int ieee_exp;
    unsigned long xport1,xport2;
    unsigned long ieee1 = 0;
    unsigned long ieee2 = 0;
    char ieee8[8];
    memcpy(ieee8,ieee,8);
    /*------get 2 longs for shifting------------------------------*/
    memcpy(((char *)&ieee1)+sizeof(unsigned long)-4,ieee8,4);
    REVERSE(&ieee1,sizeof(unsigned long));
    memcpy(((char *)&ieee2)+sizeof(unsigned long)-4,ieee8+4,4);
    REVERSE(&ieee2,sizeof(unsigned long));
    memset(xport,0,8);
    /*-----if IEEE value is missing (1st 2 bytes are FFFF)-----*/
    if (*ieee8 == (char)0xff && ieee8[1] == (char)0xff) {
        misschar = ~ieee8[2];
        *xport = (misschar == 0xD2) ? 0x6D : misschar;
        return;
    }
 
    /**************************************************************/
    /* Translate IEEE floating point number into IBM format float */
    /* */
    /* IEEE format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEEEEEMMMM ........ MMMM */
    /* */
    /* Sign bit, 11 bit exponent, 52 fraction. Exponent is excess */
    /* 1023. The fraction is multiplied by a power of 2 of the */
    /* actual exponent. Normalized floating point numbers are */
    /* represented with the binary point immediately to the left */
    /* of the fraction with an implied "1" to the left of the */
    /* binary point. */
    /* */
    /* IBM format: */
    /* */
    /* 6 5 0 */
    /* 3 5 0 */
    /* */
    /* SEEEEEEEMMMM ......... MMMM */
    /* */
    /* Sign bit, 7 bit exponent, 56 bit fraction. Exponent is */
    /* excess 64. The fraction is multiplied by a power of 16 of */
    /* of the actual exponent. Normalized floating point numbers */
    /* are presented with the radix point immediately to the left */
    /* of the high order hex fraction digit. */
    /* */
    /* How do you translate from local to IBM format? */
    /* */
    /* The ieee format gives you a number that has a power of 2 */
    /* exponent and a fraction of the form "1.<fraction bits>". */
    /* The first step is to get that "1" bit back into the */
    /* fraction. Right shift it down 1 position, set the high */
    /* order bit and reduce the binary exponent by 1. Now we have */
    /* a fraction that looks like ".1<fraction bits>" and it's */
    /* ready to be shoved into ibm format. The ibm fraction has 4 */
    /* more bits than the ieee, the ieee fraction must therefore */
    /* be shifted left 4 positions before moving it in. We must */
    /* also correct the fraction bits to account for the loss of 2*/
    /* bits when converting from a binary exponent to a hex one */
    /* (>> 2). We must shift the fraction left for 0, 1, 2, or 3 */
    /* positions to maintain the proper magnitude. Doing */
    /* conversion this way would tend to lose bits in the fraction*/
    /* which is not desirable or necessary if we cheat a bit. */
    /* First of all, we know that we are going to have to shift */
    /* the ieee fraction left 4 places to put it in the right */
    /* position; we won't do that, we'll just leave it where it is*/
    /* and increment the ibm exponent by one, this will have the */
    /* same effect and we won't have to do any shifting. Now, */
    /* since we have 4 bits in front of the fraction to work with,*/
    /* we won't lose any bits. We set the bit to the left of the */
    /* fraction which is the implicit "1" in the ieee fraction. We*/
    /* then adjust the fraction to account for the loss of bits */
    /* when going to a hex exponent. This adjustment will never */
    /* involve shifting by more than 3 positions so no bits are */
    /* lost. */
 
    /* Get ieee number less the exponent into the first half of */
    /* the ibm number */
    xport1 = ieee1 & 0x000fffff;
 
    /* get the second half of the number into the second half of */
    /* the ibm number and see if both halves are 0. If so, ibm is */
    /* also 0 and we just return */
    if ((!(xport2 = ieee2)) && !ieee1) {
        ieee_exp = 0;
        goto doret;
    }
 
    /* get the actual exponent value out of the ieee number. The */
    /* ibm fraction is a power of 16 and the ieee fraction a power*/
    /* of 2 (16 ** n == 2 ** 4n). Save the low order 2 bits since */
    /* they will get lost when we divide the exponent by 4 (right */
    /* shift by 2) and we will have to shift the fraction by the */
    /* appropriate number of bits to keep the proper magnitude. */
    shift = (int)
    (ieee_exp = (int)(((ieee1 >> 16) & 0x7ff0) >> 4) - 1023) & 3;
 
    /* the ieee format has an implied "1" immdeiately to the left */
    /* of the binary point. Show it in here. */
    xport1 |= 0x00100000;
    if (shift){
        /* set the first half of the ibm number by shifting it left */
        /* the appropriate number of bits and oring in the bits */
        /* from the lower half that would have been shifted in (if */
        /* we could shift a double). The shift count can never */
        /* exceed 3, so all we care about are the high order 3 */
        /* bits. We don't want sign extention so make sure it's an */
        /* unsigned char. We'll shift either5, 6, or 7 places to */
        /* keep 3, 2, or 1 bits. After that, shift the second half */
        /* of the number the right number of places. We always get */
        /* zero fill on left shifts. */
        xport1 = (xport1 << shift) |
        ((unsigned char) (((ieee2 >> 24) & 0xE0) >>
        (5 + (3 - shift))));
        xport2 <<= shift;
    }
 
    /* Now set the ibm exponent and the sign of the fraction. The */
    /* power of 2 ieee exponent must be divided by 4 and made */
    /* excess 64 (we add 65 here because of the poisition of the */
    /* fraction bits, essentially 4 positions lower than they */
    /* should be so we incrment the ibm exponent). */
    xport1 |= (((ieee_exp >>2) + 65) | ((ieee1 >> 24) & 0x80)) << 24;
 
    /* If the ieee exponent is greater than 248 or less than -260, */
    /* then it cannot fit in the ibm exponent field. Send back the */
    /* appropriate flag. */
    doret:
    if (-260 <= ieee_exp && ieee_exp <= 248) {
        REVERSE(&xport1,sizeof(unsigned long));
        memcpy(xport,((char *)&xport1)+sizeof(unsigned long)-4,4);
        REVERSE(&xport2,sizeof(unsigned long));
        memcpy(xport+4,((char *)&xport2)+sizeof(unsigned long)-4,4);
        return;
    }
    memset(xport,0xFF,8);
    if (ieee_exp > 248)
        *xport = 0x7f;
    return;
}
 
#ifdef DEFINE_REVERSE
void REVERSE(char *intp, int l)
{
    int i,j;
    char save;
    static int one = 1;
    #if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
        if (((unsigned char *)&one)[sizeof(one)-1] == 1)
            return;
    #endif
    j = l/2;
    for (i=0;i<j;i++) {
    save = intp[i];
    intp[i] = intp[l-i-1];
    intp[l-i-1] = save;
    }
}
#endif
В данном файле компилятор ни на что не ругается, но когда я пытаюсь этот код добавить в файл main.cpp или создать пространство имен с этим кодом, то я получаю несколько ошибок, например:
ibm_ieee.h:91:13: error: no matching function for call to 'ieee2xpt'
ibm_ieee.h:15:6: note: candidate function not viable: no known conversion from 'char *' to 'unsigned char *' for 1st argument

ibm_ieee.h:95:9: error: no matching function for call to 'xpt2ieee'
ibm_ieee.h:14:6: note: candidate function not viable: no known conversion from 'char *' to 'unsigned char *' for 1st argument

ibm_ieee.h:150:5: error: no matching function for call to 'REVERSE'
ibm_ieee.h:131:10: note: candidate function not viable: no known conversion from 'unsigned long *' to 'char *' for 1st argument
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.01.2020, 20:11
Ответы с готовыми решениями:

опять ошибка.на этот раз cannot convert `float (*)(float)' to `float' in argument passing
#include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; #include&lt;math.h&gt; float f1(float x)/*vira*enie 1*/ {return (x*cos(x))/(1+ pow(x,2));} ...

Конвертация string в float
string to float или double обычная консоль как перевести

Конвертация Float to wchar_t
Здравствуйте, уважаемые форумчане. Помогите, мне, пожалуйста. Как правильно перевести float в wchar_t? Все что я нашёл в интернете - не...

14
Злостный нарушитель
 Аватар для Verevkin
10656 / 5804 / 1282
Регистрация: 12.03.2015
Сообщений: 26,797
25.01.2020, 20:29
Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
Мне необходимо конвертировать IBM float в IEEE float.
Чем они отличаются, напиши сюда. Нинада тырить чужой кот, нада запилить свой.
1
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 491
25.01.2020, 21:00  [ТС]
Verevkin, запилить свой мне нравится
вот здесь описание стандарта IBM https://en.wikipedia.org/wiki/... ting_point
вот здесь описание стандарта IEEE https://en.wikipedia.org/wiki/IEEE_754
(на русском языке, где приводится формула https://ru.wikipedia.org/wiki/IEEE_754-2008)

Стандарт IBM также как и стандарт IEEE это стандарты представления чисел с плавающей точкой. Они используются для представления 32-х и 64-х битовых чисел.

Оба стандарта подразумевают, что число может быть представлено согласно следующей формулы:
https://www.cyberforum.ru/cgi-bin/latex.cgi?{(-1)}^{S}*C*{B}^{Q}
Где:
S=знак (0 для положительного и 1 для отрицательного);
С=мантисса (коэффициент);
Q=экспонента.
b=основание (2 или 10)

Различие между стандартами IBM и IEEE состоит в том, сколько битов отводится на мантиссу (С) и экспоненту (Q).
IBM стандарт предполагает:
1 бит для знака (S)
затем 7 битов для мантиссы (S)
и 24 бита для экспоненты (Q)

IEEE стандарт предполагает:
1 бит для знака (S)
затем 8 битов для мантиссы (S)
и 23 бита для экспоненты (Q)

Я думаю, что для конвертации одного стандарта в другой мне необходимо:
1) считать из моего файла 32 бита.
2) согласно приведенной формулы перевести двоичные знаки (биты) в десятичную систему и подставить числа в формулу. Длина мантиссы и экспоненты определяется тем, в каком стандарте записаны мои данные.
3) после подстановки чисел в формулу я получу число, которое необходимо будет перевести в другой стандарт. Здесь надо подумать как это сделать. Так как знак одинаков для IBM и для IEEE то необходимо найти двоичное представление для мантиссы и экспоненты.

Вопрос:
как мне прочитать 32 бита и получить массив из 32 чисел?
0
Злостный нарушитель
 Аватар для Verevkin
10656 / 5804 / 1282
Регистрация: 12.03.2015
Сообщений: 26,797
25.01.2020, 23:12
Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
Различие между стандартами IBM и IEEE состоит в том, сколько битов отводится на мантиссу (С) и экспоненту (Q).
Ага, я уже загулил.
Короче, стандарт IEEE - это сишный нативный тип float, в котором мантисса 23 бита и 8 - экспонента.
Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
Вопрос:
как мне прочитать 32 бита и получить массив из 32 чисел?
Это неправильный вопрос.

Надо просто определиться, куда сдвигать поля мантиссы и экспоненты. Зачем какой-то массив?
Мож начать проще вот, например, с этого?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
typedef union
{
  float native_value;
  uint32_t uint_value;
  
  struct 
  {
    uint32_t mantissa: 23;  
    uint16_t exponent:  8;
    bool     sign:      1;
  } fields_ieee;
  
  struct 
  {
    uint32_t mantissa: 24;  
    uint16_t exponent:  7;
    bool     sign:      1;
  } fields_intel;
} TFloatRec;
1
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 491
25.01.2020, 23:42  [ТС]
Verevkin, спасибо за ссылку
Со структурой я более или менее понял (плохо пока понял там слово union и typedef)

Цитата Сообщение от Verevkin Посмотреть сообщение
Надо просто определиться, куда сдвигать поля мантиссы и экспоненты. Зачем какой-то массив?
Звучит красиво, но я не совсем понимаю как мы это сделаем?
Правильно я понимаю, что сейчас для начала мы с вами хотим просто правильно отобразить число стандарта IBM?

Минимальный размер считываемого из файла объем данных это 1 байт (насколько у меня получается). Считываю байты из файла с помощью кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
QByteArray  A;
A.resize(4); // 4 байта
QBitArray   B(32); // 32 битов
 
qFile = new QFile(myFile);
uchar* memFile_uchar = qFromLittleEndian(util::bit_cast<uchar*>(qFile->map(3600, qFile->size()-3600))); // использую технику memory mapping для чтения
 
for(qint32 i = 0; i < 4; i++){ // считываю последовательно 4 байта
    A[i] = memFile_uchar[i];
    for(int b=0; b<8; ++b){
        B.setBit(i*8+b, A.at(i)&(1<<(7-b))); // записываю по 8 битов из каждого байта
        std::cout << B[b] << std::endl;
    }
}
По-моему здесь A.at(i)&(1<<(7-b)) я в неправильном направлении считываю биты, потому что когда я по формуле считаю число по стандарту IBM у меня число получается очень большое.
Кстати компьютер у меня Little Endian
Я туповат, но если я иду не в том направлении вы меня поправьте
0
Злостный нарушитель
 Аватар для Verevkin
10656 / 5804 / 1282
Регистрация: 12.03.2015
Сообщений: 26,797
26.01.2020, 00:05
Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
Со структурой я более или менее понял (плохо пока понял там слово union и typedef)
Ну, дык, напиши, для начала 200-300 программ на С/С++ и годика через 3-4 возвращайся в этот тред. Я подожду.

Добавлено через 3 минуты
Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
Я туповат, но если я иду не в том направлении вы меня поправьте
Я вижу. Тебя точно послать в нужном направлении? Это тебя огорчит.
Убери файлы, они тебе мешают.
1
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 491
26.01.2020, 00:08  [ТС]
Verevkin,
Цитата Сообщение от Verevkin Посмотреть сообщение
Я вижу. Тебя точно послать в нужном направлении? Это тебя огорчит.
можно не озвучивать, я догадался
ладно, помучаюсь
0
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
26.01.2020, 00:47
Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
Я использую Qt 5.14.0, MSVC 2017 x64, Windows 10.
С Qt не сталкивался, но если просто на уровне консольного приложения в Visual Studio, то я не очень понял сути проблемы.

В pdf-е по ссылке есть C-шная программа, которая состоит из основного файла (testieee.c) с функцией main() и файла ieee.c с собственно функцией преобразования.

Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
Проект состоит из пустого файла main.cpp, testieee.c и ieee.c и .pro файл
Здесь один файл лишний: надо либо main.cpp, либо testieee.c (про .pro не говорим, поскольку, видимо это от Qt. Да?).
Т.е. проект консольного приложения на С++ в Visual Studio в разделе Source Files должен содержать ieee.c и один из этих двух файлов.

Если вы решите использовать оригинальный testieee.c (на C), то в него необходимо внести некоторые правки:
1. Добавить inlude-ы <stdio.h> и <memory.h>. Это как минимум.
2. Привести определения и прототипы функций к стандарту ANSI C (думаю, что современный компилятор будет грязно ругаться на диалект C из 1978 года).
3. Сделать заголовочный файл для ieee.c с прототипами функций (ieee.h)
4. Заголовочный файл ieee.h включить в состав проекта (в раздел Header Files).
5. Добавить #include "ieee.h" в testieee.c.

Если вы решите использовать собственный main.cpp (на C++), то в дополнение к вышенаписанному, исходный код из testieee.c нужно будет перенести в main.cpp с попутным переводом (в большей или меньшей степени) с C на C++.

В файл ieee.c также необходимо внести правки:
1. Добавить inlude <memory.h>. Это как минимум.
2. Привести определения и прототипы функций к стандарту ANSI C.
3. Добавить #include "ieee.h".

Возможно, в самое начало testieee.c до include-ов, нужно будет добавить #define _CRT_SECURE_DEPRECATE_MEMORY, что бы компилятор не ругался на "небезопасные" функции.

После этого можно пробовать откомпилировать и запустить программу.

Для работы в другом проекте (Qt, WinAPI, MFC, etc.) нужны будут только файлы ieee.h и ieee.c.

Цитата Сообщение от Verevkin Посмотреть сообщение
Нинада тырить чужой кот, нада запилить свой.
Желание похвальное, но в данном конкретном случае, imho, не стоит изобретать велосипед.
1
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 491
26.01.2020, 02:00  [ТС]
L0M, спасибо за помощь!
да .pro файл это файл Qt который запускается с помощью QMake (наверно его можно назвать аналогом CMake).

После удаления из проекта main.cpp и добавления в testieee.c <stdio.h> и <memory.h> (то есть в проекте оставалось два файла testieee.c и ieee.c) я смог успешно запустить проект. Также я переделал объявление функций.

Как я понимаю, файл testieee.c создан для тестирования функционирования ieee.c
Так как я планирую использовать функционал ieee.c в своем проекте, то я пытаюсь создать пространство имен в заголовочном ibmieee.h файле:
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
#include <memory.h>
 
#ifndef IBMIEEE_H
#define IBMIEEE_H
 
namespace ibmieee
{
 
#define CN_TYPE_NATIVE 0
#define CN_TYPE_XPORT 1
#define CN_TYPE_IEEEB 2
#define CN_TYPE_IEEEL 3
int cnxptiee(char *from, int fromtype,char *to, int totype);
void xpt2ieee(unsigned char *xport, unsigned char *ieee);
void ieee2xpt(unsigned char *ieee, unsigned char *xport);
#ifndef FLOATREP
    #define FLOATREP get_native()
    int get_native(void);
#endif
 
/*-------------------------------------------------------------------*/
/* rc = cnxptiee(from,fromtype,to,totype); */
/* */
/* where */
/* */
/* from pointer to a floating point value */
/* fromtype type of floating point value (see below) */
/* to pointer to target area */
/* totype type of target value (see below) */
/* */
/* floating point types: */
/* 0 native floating point */
/* 1 IBM mainframe (transport representation) */
/* 2 Big endian IEEE floating point */
/* 3 Little endian IEEE floating point */
/* */
/* rc = cnxptiee(from,0,to,1); native -> transport */
/* rc = cnxptiee(from,0,to,2); native -> Big endian IEEE */
/* rc = cnxptiee(from,0,to,3); native -> Little endian IEEE */
/* rc = cnxptiee(from,1,to,0); transport -> native */
/* rc = cnxptiee(from,1,to,2); transport -> Big endian IEEE */
/* rc = cnxptiee(from,1,to,3); transport -> Little endian IEEE */
/* rc = cnxptiee(from,2,to,0); Big endian IEEE -> native */
/* rc = cnxptiee(from,2,to,1); Big endian IEEE -> transport */
/* rc = cnxptiee(from,2,to,3); Big endian IEEE -> Little endian IEEE */
/* rc = cnxptiee(from,3,to,0); Little endian IEEE -> native */
/* rc = cnxptiee(from,3,to,1); Little endian IEEE -> transport */
/* rc = cnxptiee(from,3,to,2); Little endian IEEE -> Big endian IEEE */
/*-------------------------------------------------------------------*/
int cnxptiee(char *from, int fromtype, char *to, int totype){
    char temp[8];
    int i;
    if (fromtype == CN_TYPE_NATIVE) {
        fromtype = FLOATREP;
    }
    switch(fromtype) {
        case CN_TYPE_IEEEL :
        if (totype == CN_TYPE_IEEEL)
            break;
        for (i=7;i>=0;i--) {
            temp[7-i] = from[i];
        }
        from = temp;
        fromtype = CN_TYPE_IEEEB;
        /* break intentionally omitted */
        case CN_TYPE_IEEEB :
        /* break intentionally omitted */
        case CN_TYPE_XPORT :
        break;
        default:
        return(-1);
    }
    if (totype == CN_TYPE_NATIVE) {
        totype = FLOATREP;
    }
    switch(totype) {
        case CN_TYPE_XPORT :
        case CN_TYPE_IEEEB :
        case CN_TYPE_IEEEL :
        break;
        default:
        return(-2);
    }
    if (fromtype == totype) {
        memcpy(to,from,8);
        return(0);
    }
    switch(fromtype) {
        case CN_TYPE_IEEEB :
        if (totype == CN_TYPE_XPORT)
            ieee2xpt(from,to);
        else memcpy(to,from,8);
            break;
        case CN_TYPE_XPORT :
            xpt2ieee(from,to);
            break;
    }
    if (totype == CN_TYPE_IEEEL) {
        memcpy(temp,to,8);
        for (i=7;i>=0;i--) {
            to[7-i] = temp[i];
        }
    }
    return(0);
}
 
int get_native() {
    static char float_reps[][8] = {
        {0x41,0x10,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x3f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f}};
    static double one = 1.00;
    int i,j;
    j = sizeof(float_reps)/8;
    for (i=0;i<j;i++) {
        if (memcmp(&one,float_reps+i,8) == 0)
            return(i+1);
    }
    return(-1);
}
 
#ifdef BIG_ENDIAN
    #define REVERSE(a,b)
#endif
#ifdef LITTLE_ENDIAN
    #define DEFINE_REVERSE
    void REVERSE();
#endif
#if !defined(DEFINE_REVERSE) && !defined(REVERSE)
    #define DEFINE_REVERSE
    void REVERSE(char *intp, int l);
#endif
void xpt2ieee(unsigned char *xport, unsigned char *ieee){
    char temp[8];
    register int shift;
    register int nib;
    unsigned long ieee1,ieee2;
    unsigned long xport1 = 0;
    unsigned long xport2 = 0;
    memcpy(temp,xport,8);
    memset(ieee,0,8);
    if (*temp && memcmp(temp+1,ieee,7) == 0) {
        ieee[0] = ieee[1] = 0xff;
        ieee[2] = ~(*temp);
        return;
    }
    memcpy(((char *)&xport1)+sizeof(unsigned long)-4,temp,4);
    REVERSE(&xport1,sizeof(unsigned long));
    memcpy(((char *)&xport2)+sizeof(unsigned long)-4,temp+4,4);
    REVERSE(&xport2,sizeof(unsigned long));
    /***************************************************************/
    /* Translate IBM format floating point numbers into IEEE */
    /* format floating point numbers. */
    /* */
    /* IEEE format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEEEEEMMMM ............ MMMM */
    /* */
    /* Sign bit, 11 bits exponent, 52 bit fraction. Exponent is */
    /* excess 1023. The fraction is multiplied by a power of 2 of */
    /* the actual exponent. Normalized floating point numbers are */
    /* represented with the binary point immediately to the left */
    /* of the fraction with an implied "1" to the left of the */
    /* binary point. */
    /* */
    /* IBM format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEMMMM ......... MMMM */
    /* */
    /* Sign bit, 7 bit exponent, 56 bit fraction. Exponent is */
    /* excess 64. The fraction is multiplied by a power of 16 of */
    /* the actual exponent. Normalized floating point numbers are */
    /* represented with the radix point immediately to the left of*/
    /* the high order hex fraction digit. */
    /* */
    /* How do you translate from IBM format to IEEE? */
    /* */
    /* Translating back to ieee format from ibm is easier than */
    /* going the other way. You lose at most, 3 bits of fraction, */
    /* but nothing can be done about that. The only tricky parts */
    /* are setting up the correct binary exponent from the ibm */
    /* hex exponent, and removing the implicit "1" bit of the ieee*/
    /* fraction (see vzctdbl). We must shift down the high order */
    /* nibble of the ibm fraction until it is 1. This is the */
    /* implicit 1. The bit is then cleared and the exponent */
    /* adjusted by the number of positions shifted. A more */
    /* thorough discussion is in vzctdbl.c. */
    /* Get the first half of the ibm number without the exponent */
    /* into the ieee number */
    ieee1 = xport1 & 0x00ffffff;
    /* get the second half of the ibm number into the second half */
    /* of the ieee number . If both halves were 0. then just */
    /* return since the ieee number is zero. */
    if ((!(ieee2 = xport2)) && !xport1)
        return;
    /* The fraction bit to the left of the binary point in the */
    /* ieee format was set and the number was shifted 0, 1, 2, or */
    /* 3 places. This will tell us how to adjust the ibm exponent */
    /* to be a power of 2 ieee exponent and how to shift the */
    /* fraction bits to restore the correct magnitude. */
    if ((nib = (int)xport1) & 0x00800000)
        shift = 3;
    else if (nib & 0x00400000)
        shift = 2;
    else if (nib & 0x00200000)
        shift = 1;
    else
        shift = 0;
    if (shift){
        /* shift the ieee number down the correct number of places */
        /* then set the second half of the ieee number to be the */
        /* second half of the ibm number shifted appropriately, */
        /* ored with the bits from the first half that would have */
        /* been shifted in if we could shift a double. All we are */
        /* worried about are the low order 3 bits of the first */
        /* half since we're only shifting by 1, 2, or 3. */
        ieee1 >>= shift;
        ieee2 = (xport2 >> shift) |
        ((xport1 & 0x00000007) << (29 + (3 - shift)));
    }
    /* clear the 1 bit to the left of the binary point */
    ieee1 &= 0xffefffff;
    /* set the exponent of the ieee number to be the actual */
    /* exponent plus the shift count + 1023. Or this into the */
    /* first half of the ieee number. The ibm exponent is excess */
    /* 64 but is adjusted by 65 since during conversion to ibm */
    /* format the exponent is incremented by 1 and the fraction */
    /* bits left 4 positions to the right of the radix point. */
    ieee1 |= (((((long)(*temp & 0x7f) - 65) << 2) + shift + 1023) << 20) | (xport1 & 0x80000000);
    REVERSE(&ieee1,sizeof(unsigned long));
    memcpy(ieee,((char *)&ieee1)+sizeof(unsigned long)-4,4);
    REVERSE(&ieee2,sizeof(unsigned long));
    memcpy(ieee+4,((char *)&ieee2)+sizeof(unsigned long)-4,4);
    return;
}
/*-------------------------------------------------------------*/
/* Name: ieee2xpt */
/* Purpose: converts IEEE to transport */
/* Usage: rc = ieee2xpt(to_ieee,p_data); */
/* Notes: this routine is an adaptation of the wzctdbl routine */
/* from the Apollo. */
/*-------------------------------------------------------------*/
 
 
void ieee2xpt(unsigned char *ieee, unsigned char *xport) /* ieee ptr to IEEE field (2-8 bytes) */ /* xport ptr to xport format (8 bytes) */
{
    register int shift;
    unsigned char misschar;
    int ieee_exp;
    unsigned long xport1,xport2;
    unsigned long ieee1 = 0;
    unsigned long ieee2 = 0;
    char ieee8[8];
    memcpy(ieee8,ieee,8);
    /*------get 2 longs for shifting------------------------------*/
    memcpy(((char *)&ieee1)+sizeof(unsigned long)-4,ieee8,4);
    REVERSE(&ieee1,sizeof(unsigned long));
    memcpy(((char *)&ieee2)+sizeof(unsigned long)-4,ieee8+4,4);
    REVERSE(&ieee2,sizeof(unsigned long));
    memset(xport,0,8);
    /*-----if IEEE value is missing (1st 2 bytes are FFFF)-----*/
    if (*ieee8 == (char)0xff && ieee8[1] == (char)0xff) {
        misschar = ~ieee8[2];
        *xport = (misschar == 0xD2) ? 0x6D : misschar;
        return;
    }
 
    /**************************************************************/
    /* Translate IEEE floating point number into IBM format float */
    /* */
    /* IEEE format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEEEEEMMMM ........ MMMM */
    /* */
    /* Sign bit, 11 bit exponent, 52 fraction. Exponent is excess */
    /* 1023. The fraction is multiplied by a power of 2 of the */
    /* actual exponent. Normalized floating point numbers are */
    /* represented with the binary point immediately to the left */
    /* of the fraction with an implied "1" to the left of the */
    /* binary point. */
    /* */
    /* IBM format: */
    /* */
    /* 6 5 0 */
    /* 3 5 0 */
    /* */
    /* SEEEEEEEMMMM ......... MMMM */
    /* */
    /* Sign bit, 7 bit exponent, 56 bit fraction. Exponent is */
    /* excess 64. The fraction is multiplied by a power of 16 of */
    /* of the actual exponent. Normalized floating point numbers */
    /* are presented with the radix point immediately to the left */
    /* of the high order hex fraction digit. */
    /* */
    /* How do you translate from local to IBM format? */
    /* */
    /* The ieee format gives you a number that has a power of 2 */
    /* exponent and a fraction of the form "1.<fraction bits>". */
    /* The first step is to get that "1" bit back into the */
    /* fraction. Right shift it down 1 position, set the high */
    /* order bit and reduce the binary exponent by 1. Now we have */
    /* a fraction that looks like ".1<fraction bits>" and it's */
    /* ready to be shoved into ibm format. The ibm fraction has 4 */
    /* more bits than the ieee, the ieee fraction must therefore */
    /* be shifted left 4 positions before moving it in. We must */
    /* also correct the fraction bits to account for the loss of 2*/
    /* bits when converting from a binary exponent to a hex one */
    /* (>> 2). We must shift the fraction left for 0, 1, 2, or 3 */
    /* positions to maintain the proper magnitude. Doing */
    /* conversion this way would tend to lose bits in the fraction*/
    /* which is not desirable or necessary if we cheat a bit. */
    /* First of all, we know that we are going to have to shift */
    /* the ieee fraction left 4 places to put it in the right */
    /* position; we won't do that, we'll just leave it where it is*/
    /* and increment the ibm exponent by one, this will have the */
    /* same effect and we won't have to do any shifting. Now, */
    /* since we have 4 bits in front of the fraction to work with,*/
    /* we won't lose any bits. We set the bit to the left of the */
    /* fraction which is the implicit "1" in the ieee fraction. We*/
    /* then adjust the fraction to account for the loss of bits */
    /* when going to a hex exponent. This adjustment will never */
    /* involve shifting by more than 3 positions so no bits are */
    /* lost. */
 
    /* Get ieee number less the exponent into the first half of */
    /* the ibm number */
    xport1 = ieee1 & 0x000fffff;
 
    /* get the second half of the number into the second half of */
    /* the ibm number and see if both halves are 0. If so, ibm is */
    /* also 0 and we just return */
    if ((!(xport2 = ieee2)) && !ieee1) {
        ieee_exp = 0;
        goto doret;
    }
 
    /* get the actual exponent value out of the ieee number. The */
    /* ibm fraction is a power of 16 and the ieee fraction a power*/
    /* of 2 (16 ** n == 2 ** 4n). Save the low order 2 bits since */
    /* they will get lost when we divide the exponent by 4 (right */
    /* shift by 2) and we will have to shift the fraction by the */
    /* appropriate number of bits to keep the proper magnitude. */
    shift = (int)
    (ieee_exp = (int)(((ieee1 >> 16) & 0x7ff0) >> 4) - 1023) & 3;
 
    /* the ieee format has an implied "1" immdeiately to the left */
    /* of the binary point. Show it in here. */
    xport1 |= 0x00100000;
    if (shift){
        /* set the first half of the ibm number by shifting it left */
        /* the appropriate number of bits and oring in the bits */
        /* from the lower half that would have been shifted in (if */
        /* we could shift a double). The shift count can never */
        /* exceed 3, so all we care about are the high order 3 */
        /* bits. We don't want sign extention so make sure it's an */
        /* unsigned char. We'll shift either5, 6, or 7 places to */
        /* keep 3, 2, or 1 bits. After that, shift the second half */
        /* of the number the right number of places. We always get */
        /* zero fill on left shifts. */
        xport1 = (xport1 << shift) |
        ((unsigned char) (((ieee2 >> 24) & 0xE0) >>
        (5 + (3 - shift))));
        xport2 <<= shift;
    }
 
    /* Now set the ibm exponent and the sign of the fraction. The */
    /* power of 2 ieee exponent must be divided by 4 and made */
    /* excess 64 (we add 65 here because of the poisition of the */
    /* fraction bits, essentially 4 positions lower than they */
    /* should be so we incrment the ibm exponent). */
    xport1 |= (((ieee_exp >>2) + 65) | ((ieee1 >> 24) & 0x80)) << 24;
 
    /* If the ieee exponent is greater than 248 or less than -260, */
    /* then it cannot fit in the ibm exponent field. Send back the */
    /* appropriate flag. */
    doret:
    if (-260 <= ieee_exp && ieee_exp <= 248) {
        REVERSE(&xport1,sizeof(unsigned long));
        memcpy(xport,((char *)&xport1)+sizeof(unsigned long)-4,4);
        REVERSE(&xport2,sizeof(unsigned long));
        memcpy(xport+4,((char *)&xport2)+sizeof(unsigned long)-4,4);
        return;
    }
    memset(xport,0xFF,8);
    if (ieee_exp > 248)
        *xport = 0x7f;
    return;
}
 
#ifdef DEFINE_REVERSE
void REVERSE(char *intp, int l)
{
    int i,j;
    char save;
    static int one = 1;
    #if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
        if (((unsigned char *)&one)[sizeof(one)-1] == 1)
            return;
    #endif
    j = l/2;
    for (i=0;i<j;i++) {
    save = intp[i];
    intp[i] = intp[l-i-1];
    intp[l-i-1] = save;
    }
}
#endif
 
 
} // namespace util
 
 
#endif // IBMIEEE_H
Но теперь там, где в этом файле вызываются методы методы этого же файла (ieee2xpt(from,to); xpt2ieee(from,to); REVERSE(&xport1,sizeof(unsigned long)) возникают ошибки:
ibmieee.h:148:5: error: no matching function for call to 'REVERSE'
ibmieee.h:131:10: note: candidate function not viable: no known conversion from 'unsigned long *' to 'char *' for 1st argument

Помимо этого, я заметил, что если я файл ieee.c переименую в ieee.cpp, то я получаю такие же ошибки, и мой проект из двух файлов testieee.c и ieee.cpp становится нерабочим. Из-за чего так происходит?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
26.01.2020, 02:13
Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
Из-за чего так происходит?
Из-за того, что С и С++ разные языки

В С нет пространств имен.

Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
no known conversion from 'unsigned long *' to 'char *' for 1st argument
C++
1
2
3
4
5
6
7
8
9
10
11
#ifdef BIG_ENDIAN
    #define REVERSE(a,b)
#endif
#ifdef LITTLE_ENDIAN
    #define DEFINE_REVERSE
    void REVERSE();
#endif
#if !defined(DEFINE_REVERSE) && !defined(REVERSE)
    #define DEFINE_REVERSE
    void REVERSE(void *intp, int l);
#endif
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifdef DEFINE_REVERSE
void REVERSE(void * intpv, int l)
{
    int i,j;
    char save;
    char * intp = (char *)intpv;
    static int one = 1;
    #if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
        if (((unsigned char *)&one)[sizeof(one)-1] == 1)
            return;
    #endif
    j = l/2;
    for (i=0;i<j;i++) {
    save = intp[i];
    intp[i] = intp[l-i-1];
    intp[l-i-1] = save;
    }
}
#endif
1
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 491
26.01.2020, 02:29  [ТС]
DrOffset, буду иметь ввиду, спасибо
не подскажите, почему мы заменили char * intpv на void * intpv? У меня такие же ошибки и для методов ieee2xpt(from,to); xpt2ieee(from,to);
пытаюсь понять, мне там по аналогии заменить тип первого аргумента на void?
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
26.01.2020, 02:44
Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
не подскажите, почему мы заменили char * intpv на void * intpv?
Потому что unsigned long * не приводится к char *. А к void * приводится.
В некоторых старых компиляторах С void * был синонимом char *, поэтому этот код работал.

Цитата Сообщение от Kerim_Geophysic Посмотреть сообщение
мне там по аналогии заменить тип первого аргумента на void?
Нет. Там unsigned char * и char *. Нужно из них что-то одно выбрать.
1
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 491
26.01.2020, 03:26  [ТС]
DrOffset, спасибо, изменил
У меня заголовочный файл выглядит следующим образом:
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
#include <memory.h>
 
#ifndef IBMIEEE_H
#define IBMIEEE_H
 
namespace ibmieee
{
 
#define CN_TYPE_NATIVE 0
#define CN_TYPE_XPORT 1
#define CN_TYPE_IEEEB 2
#define CN_TYPE_IEEEL 3
int cnxptiee(char, int,char, int);
void xpt2ieee(char *, char *);
void ieee2xpt(char *, char *);
#ifndef FLOATREP
    #define FLOATREP get_native()
    int get_native(void);
#endif
 
/*-------------------------------------------------------------------*/
/* rc = cnxptiee(from,fromtype,to,totype); */
/* */
/* where */
/* */
/* from pointer to a floating point value */
/* fromtype type of floating point value (see below) */
/* to pointer to target area */
/* totype type of target value (see below) */
/* */
/* floating point types: */
/* 0 native floating point */
/* 1 IBM mainframe (transport representation) */
/* 2 Big endian IEEE floating point */
/* 3 Little endian IEEE floating point */
/* */
/* rc = cnxptiee(from,0,to,1); native -> transport */
/* rc = cnxptiee(from,0,to,2); native -> Big endian IEEE */
/* rc = cnxptiee(from,0,to,3); native -> Little endian IEEE */
/* rc = cnxptiee(from,1,to,0); transport -> native */
/* rc = cnxptiee(from,1,to,2); transport -> Big endian IEEE */
/* rc = cnxptiee(from,1,to,3); transport -> Little endian IEEE */
/* rc = cnxptiee(from,2,to,0); Big endian IEEE -> native */
/* rc = cnxptiee(from,2,to,1); Big endian IEEE -> transport */
/* rc = cnxptiee(from,2,to,3); Big endian IEEE -> Little endian IEEE */
/* rc = cnxptiee(from,3,to,0); Little endian IEEE -> native */
/* rc = cnxptiee(from,3,to,1); Little endian IEEE -> transport */
/* rc = cnxptiee(from,3,to,2); Little endian IEEE -> Big endian IEEE */
/*-------------------------------------------------------------------*/
int cnxptiee(char *from, int fromtype, char *to, int totype){
    char temp[8];
    int i;
    if (fromtype == CN_TYPE_NATIVE) {
        fromtype = FLOATREP;
    }
    switch(fromtype) {
        case CN_TYPE_IEEEL :
        if (totype == CN_TYPE_IEEEL)
            break;
        for (i=7;i>=0;i--) {
            temp[7-i] = from[i];
        }
        from = temp;
        fromtype = CN_TYPE_IEEEB;
        /* break intentionally omitted */
        case CN_TYPE_IEEEB :
        /* break intentionally omitted */
        case CN_TYPE_XPORT :
        break;
        default:
        return(-1);
    }
    if (totype == CN_TYPE_NATIVE) {
        totype = FLOATREP;
    }
    switch(totype) {
        case CN_TYPE_XPORT :
        case CN_TYPE_IEEEB :
        case CN_TYPE_IEEEL :
        break;
        default:
        return(-2);
    }
    if (fromtype == totype) {
        memcpy(to,from,8);
        return(0);
    }
    switch(fromtype) {
        case CN_TYPE_IEEEB :
        if (totype == CN_TYPE_XPORT)
            ieee2xpt(from,to);
        else memcpy(to,from,8);
            break;
        case CN_TYPE_XPORT :
            xpt2ieee(from,to);
            break;
    }
    if (totype == CN_TYPE_IEEEL) {
        memcpy(temp,to,8);
        for (i=7;i>=0;i--) {
            to[7-i] = temp[i];
        }
    }
    return(0);
}
 
int get_native() {
    static char float_reps[][8] = {
        {0x41,0x10,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x3f,static_cast<char>(0xf0),0x00,0x00,0x00,0x00,0x00,0x00},
        {0x00,0x00,0x00,0x00,0x00,0x00,static_cast<char>(0xf0),0x3f}};
    static double one = 1.00;
    int i,j;
    j = sizeof(float_reps)/8;
    for (i=0;i<j;i++) {
        if (memcmp(&one,float_reps+i,8) == 0)
            return(i+1);
    }
    return(-1);
}
 
#ifdef BIG_ENDIAN
    #define REVERSE(a,b)
#endif
#ifdef LITTLE_ENDIAN
    #define DEFINE_REVERSE
    void REVERSE();
#endif
#if !defined(DEFINE_REVERSE) && !defined(REVERSE)
    #define DEFINE_REVERSE
    void REVERSE(void *, int);
#endif
void xpt2ieee(unsigned char *xport, unsigned char *ieee){
    char temp[8];
    register int shift;
    register int nib;
    unsigned long ieee1,ieee2;
    unsigned long xport1 = 0;
    unsigned long xport2 = 0;
    memcpy(temp,xport,8);
    memset(ieee,0,8);
    if (*temp && memcmp(temp+1,ieee,7) == 0) {
        ieee[0] = ieee[1] = 0xff;
        ieee[2] = ~(*temp);
        return;
    }
    memcpy(((char *)&xport1)+sizeof(unsigned long)-4,temp,4);
    REVERSE(&xport1,sizeof(unsigned long));
    memcpy(((char *)&xport2)+sizeof(unsigned long)-4,temp+4,4);
    REVERSE(&xport2,sizeof(unsigned long));
    /***************************************************************/
    /* Translate IBM format floating point numbers into IEEE */
    /* format floating point numbers. */
    /* */
    /* IEEE format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEEEEEMMMM ............ MMMM */
    /* */
    /* Sign bit, 11 bits exponent, 52 bit fraction. Exponent is */
    /* excess 1023. The fraction is multiplied by a power of 2 of */
    /* the actual exponent. Normalized floating point numbers are */
    /* represented with the binary point immediately to the left */
    /* of the fraction with an implied "1" to the left of the */
    /* binary point. */
    /* */
    /* IBM format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEMMMM ......... MMMM */
    /* */
    /* Sign bit, 7 bit exponent, 56 bit fraction. Exponent is */
    /* excess 64. The fraction is multiplied by a power of 16 of */
    /* the actual exponent. Normalized floating point numbers are */
    /* represented with the radix point immediately to the left of*/
    /* the high order hex fraction digit. */
    /* */
    /* How do you translate from IBM format to IEEE? */
    /* */
    /* Translating back to ieee format from ibm is easier than */
    /* going the other way. You lose at most, 3 bits of fraction, */
    /* but nothing can be done about that. The only tricky parts */
    /* are setting up the correct binary exponent from the ibm */
    /* hex exponent, and removing the implicit "1" bit of the ieee*/
    /* fraction (see vzctdbl). We must shift down the high order */
    /* nibble of the ibm fraction until it is 1. This is the */
    /* implicit 1. The bit is then cleared and the exponent */
    /* adjusted by the number of positions shifted. A more */
    /* thorough discussion is in vzctdbl.c. */
    /* Get the first half of the ibm number without the exponent */
    /* into the ieee number */
    ieee1 = xport1 & 0x00ffffff;
    /* get the second half of the ibm number into the second half */
    /* of the ieee number . If both halves were 0. then just */
    /* return since the ieee number is zero. */
    if ((!(ieee2 = xport2)) && !xport1)
        return;
    /* The fraction bit to the left of the binary point in the */
    /* ieee format was set and the number was shifted 0, 1, 2, or */
    /* 3 places. This will tell us how to adjust the ibm exponent */
    /* to be a power of 2 ieee exponent and how to shift the */
    /* fraction bits to restore the correct magnitude. */
    if ((nib = (int)xport1) & 0x00800000)
        shift = 3;
    else if (nib & 0x00400000)
        shift = 2;
    else if (nib & 0x00200000)
        shift = 1;
    else
        shift = 0;
    if (shift){
        /* shift the ieee number down the correct number of places */
        /* then set the second half of the ieee number to be the */
        /* second half of the ibm number shifted appropriately, */
        /* ored with the bits from the first half that would have */
        /* been shifted in if we could shift a double. All we are */
        /* worried about are the low order 3 bits of the first */
        /* half since we're only shifting by 1, 2, or 3. */
        ieee1 >>= shift;
        ieee2 = (xport2 >> shift) |
        ((xport1 & 0x00000007) << (29 + (3 - shift)));
    }
    /* clear the 1 bit to the left of the binary point */
    ieee1 &= 0xffefffff;
    /* set the exponent of the ieee number to be the actual */
    /* exponent plus the shift count + 1023. Or this into the */
    /* first half of the ieee number. The ibm exponent is excess */
    /* 64 but is adjusted by 65 since during conversion to ibm */
    /* format the exponent is incremented by 1 and the fraction */
    /* bits left 4 positions to the right of the radix point. */
    ieee1 |= (((((long)(*temp & 0x7f) - 65) << 2) + shift + 1023) << 20) | (xport1 & 0x80000000);
    REVERSE(&ieee1,sizeof(unsigned long));
    memcpy(ieee,((char *)&ieee1)+sizeof(unsigned long)-4,4);
    REVERSE(&ieee2,sizeof(unsigned long));
    memcpy(ieee+4,((char *)&ieee2)+sizeof(unsigned long)-4,4);
    return;
}
/*-------------------------------------------------------------*/
/* Name: ieee2xpt */
/* Purpose: converts IEEE to transport */
/* Usage: rc = ieee2xpt(to_ieee,p_data); */
/* Notes: this routine is an adaptation of the wzctdbl routine */
/* from the Apollo. */
/*-------------------------------------------------------------*/
 
 
void ieee2xpt(unsigned char *ieee, unsigned char *xport) /* ieee ptr to IEEE field (2-8 bytes) */ /* xport ptr to xport format (8 bytes) */
{
    register int shift;
    unsigned char misschar;
    int ieee_exp;
    unsigned long xport1,xport2;
    unsigned long ieee1 = 0;
    unsigned long ieee2 = 0;
    char ieee8[8];
    memcpy(ieee8,ieee,8);
    /*------get 2 longs for shifting------------------------------*/
    memcpy(((char *)&ieee1)+sizeof(unsigned long)-4,ieee8,4);
    REVERSE(&ieee1,sizeof(unsigned long));
    memcpy(((char *)&ieee2)+sizeof(unsigned long)-4,ieee8+4,4);
    REVERSE(&ieee2,sizeof(unsigned long));
    memset(xport,0,8);
    /*-----if IEEE value is missing (1st 2 bytes are FFFF)-----*/
    if (*ieee8 == (char)0xff && ieee8[1] == (char)0xff) {
        misschar = ~ieee8[2];
        *xport = (misschar == 0xD2) ? 0x6D : misschar;
        return;
    }
 
    /**************************************************************/
    /* Translate IEEE floating point number into IBM format float */
    /* */
    /* IEEE format: */
    /* */
    /* 6 5 0 */
    /* 3 1 0 */
    /* */
    /* SEEEEEEEEEEEMMMM ........ MMMM */
    /* */
    /* Sign bit, 11 bit exponent, 52 fraction. Exponent is excess */
    /* 1023. The fraction is multiplied by a power of 2 of the */
    /* actual exponent. Normalized floating point numbers are */
    /* represented with the binary point immediately to the left */
    /* of the fraction with an implied "1" to the left of the */
    /* binary point. */
    /* */
    /* IBM format: */
    /* */
    /* 6 5 0 */
    /* 3 5 0 */
    /* */
    /* SEEEEEEEMMMM ......... MMMM */
    /* */
    /* Sign bit, 7 bit exponent, 56 bit fraction. Exponent is */
    /* excess 64. The fraction is multiplied by a power of 16 of */
    /* of the actual exponent. Normalized floating point numbers */
    /* are presented with the radix point immediately to the left */
    /* of the high order hex fraction digit. */
    /* */
    /* How do you translate from local to IBM format? */
    /* */
    /* The ieee format gives you a number that has a power of 2 */
    /* exponent and a fraction of the form "1.<fraction bits>". */
    /* The first step is to get that "1" bit back into the */
    /* fraction. Right shift it down 1 position, set the high */
    /* order bit and reduce the binary exponent by 1. Now we have */
    /* a fraction that looks like ".1<fraction bits>" and it's */
    /* ready to be shoved into ibm format. The ibm fraction has 4 */
    /* more bits than the ieee, the ieee fraction must therefore */
    /* be shifted left 4 positions before moving it in. We must */
    /* also correct the fraction bits to account for the loss of 2*/
    /* bits when converting from a binary exponent to a hex one */
    /* (>> 2). We must shift the fraction left for 0, 1, 2, or 3 */
    /* positions to maintain the proper magnitude. Doing */
    /* conversion this way would tend to lose bits in the fraction*/
    /* which is not desirable or necessary if we cheat a bit. */
    /* First of all, we know that we are going to have to shift */
    /* the ieee fraction left 4 places to put it in the right */
    /* position; we won't do that, we'll just leave it where it is*/
    /* and increment the ibm exponent by one, this will have the */
    /* same effect and we won't have to do any shifting. Now, */
    /* since we have 4 bits in front of the fraction to work with,*/
    /* we won't lose any bits. We set the bit to the left of the */
    /* fraction which is the implicit "1" in the ieee fraction. We*/
    /* then adjust the fraction to account for the loss of bits */
    /* when going to a hex exponent. This adjustment will never */
    /* involve shifting by more than 3 positions so no bits are */
    /* lost. */
 
    /* Get ieee number less the exponent into the first half of */
    /* the ibm number */
    xport1 = ieee1 & 0x000fffff;
 
    /* get the second half of the number into the second half of */
    /* the ibm number and see if both halves are 0. If so, ibm is */
    /* also 0 and we just return */
    if ((!(xport2 = ieee2)) && !ieee1) {
        ieee_exp = 0;
        goto doret;
    }
 
    /* get the actual exponent value out of the ieee number. The */
    /* ibm fraction is a power of 16 and the ieee fraction a power*/
    /* of 2 (16 ** n == 2 ** 4n). Save the low order 2 bits since */
    /* they will get lost when we divide the exponent by 4 (right */
    /* shift by 2) and we will have to shift the fraction by the */
    /* appropriate number of bits to keep the proper magnitude. */
    shift = (int)
    (ieee_exp = (int)(((ieee1 >> 16) & 0x7ff0) >> 4) - 1023) & 3;
 
    /* the ieee format has an implied "1" immdeiately to the left */
    /* of the binary point. Show it in here. */
    xport1 |= 0x00100000;
    if (shift){
        /* set the first half of the ibm number by shifting it left */
        /* the appropriate number of bits and oring in the bits */
        /* from the lower half that would have been shifted in (if */
        /* we could shift a double). The shift count can never */
        /* exceed 3, so all we care about are the high order 3 */
        /* bits. We don't want sign extention so make sure it's an */
        /* unsigned char. We'll shift either5, 6, or 7 places to */
        /* keep 3, 2, or 1 bits. After that, shift the second half */
        /* of the number the right number of places. We always get */
        /* zero fill on left shifts. */
        xport1 = (xport1 << shift) |
        ((unsigned char) (((ieee2 >> 24) & 0xE0) >>
        (5 + (3 - shift))));
        xport2 <<= shift;
    }
 
    /* Now set the ibm exponent and the sign of the fraction. The */
    /* power of 2 ieee exponent must be divided by 4 and made */
    /* excess 64 (we add 65 here because of the poisition of the */
    /* fraction bits, essentially 4 positions lower than they */
    /* should be so we incrment the ibm exponent). */
    xport1 |= (((ieee_exp >>2) + 65) | ((ieee1 >> 24) & 0x80)) << 24;
 
    /* If the ieee exponent is greater than 248 or less than -260, */
    /* then it cannot fit in the ibm exponent field. Send back the */
    /* appropriate flag. */
    doret:
    if (-260 <= ieee_exp && ieee_exp <= 248) {
        REVERSE(&xport1,sizeof(unsigned long));
        memcpy(xport,((char *)&xport1)+sizeof(unsigned long)-4,4);
        REVERSE(&xport2,sizeof(unsigned long));
        memcpy(xport+4,((char *)&xport2)+sizeof(unsigned long)-4,4);
        return;
    }
    memset(xport,0xFF,8);
    if (ieee_exp > 248)
        *xport = 0x7f;
    return;
}
 
#ifdef DEFINE_REVERSE
void REVERSE(void * intpv, int l)
{
    int i,j;
    char save;
    char * intp = (char *)intpv;
    static int one = 1;
    #if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
        if (((unsigned char *)&one)[sizeof(one)-1] == 1)
            return;
    #endif
    j = l/2;
    for (i=0;i<j;i++) {
    save = intp[i];
    intp[i] = intp[l-i-1];
    intp[l-i-1] = save;
    }
}
#endif
 
 
} // namespace util
 
 
#endif // IBMIEEE_H
Компилятор ошибок не показывает, но при сборке ошибки появляются:
ошибка: LNK2005: "int __cdecl ibmieee::get_native(void)" (?get_native@ibmieee@@YAHXZ) already defined in main.obj
ошибка: LNK2005: "int __cdecl ibmieee::cnxptiee(char *,int,char *,int)" (?cnxptiee@ibmieee@@YAHPEADH0H@Z) already defined in main.obj
ошибка: LNK2005: "void __cdecl ibmieee::REVERSE(void *,int)" (?REVERSE@ibmieee@@YAXPEAXH@Z) already defined in main.obj
ошибка: LNK2005: "void __cdecl ibmieee::xpt2ieee(unsigned char *,unsigned char *)" (?xpt2ieee@ibmieee@@YAXPEAE0@Z) already defined in main.obj
ошибка: LNK2005: "void __cdecl ibmieee::ieee2xpt(unsigned char *,unsigned char *)" (?ieee2xpt@ibmieee@@YAXPEAE0@Z) already defined in main.obj

Правильно ли я понимаю, что несколько раз определяю указанные методы?
Мне кажется, что определяю я их один раз, а также по одному разу их определяю.
Определяю вот так:
C++
1
int get_native() {}
а объявляю так:
C++
1
int get_native()
Еще вылазят такие ошибки:
main.obj:-1: ошибка: LNK2019: unresolved external symbol "void __cdecl ibmieee::xpt2ieee(char *,char *)" (?xpt2ieee@ibmieee@@YAXPEAD0@Z) referenced in function "int __cdecl ibmieee::cnxptiee(char *,int,char *,int)" (?cnxptiee@ibmieee@@YAHPEADH0H@Z)
readsegy.obj:-1: ошибка: LNK2001: unresolved external symbol "void __cdecl ibmieee::xpt2ieee(char *,char *)" (?xpt2ieee@ibmieee@@YAXPEAD0@Z)
main.obj:-1: ошибка: LNK2019: unresolved external symbol "void __cdecl ibmieee::ieee2xpt(char *,char *)" (?ieee2xpt@ibmieee@@YAXPEAD0@Z) referenced in function "int __cdecl ibmieee::cnxptiee(char *,int,char *,int)" (?cnxptiee@ibmieee@@YAHPEADH0H@Z)
readsegy.obj:-1: ошибка: LNK2001: unresolved external symbol "void __cdecl ibmieee::ieee2xpt(char *,char *)" (?ieee2xpt@ibmieee@@YAXPEAD0@Z)
debug\ReadSegy.exe:-1: ошибка: LNK1120: 2 unresolved externals
0
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
26.01.2020, 04:40
Лучший ответ Сообщение было отмечено Kerim_Geophysic как решение

Решение

Kerim_Geophysic, как-то мне не понравился ваш код из #13: оформлено вроде как заголовочный файл (.h), а содержимое - реализации функций (как в .cpp). Есть подозрение, что вы не реализовали полностью то, что я вам написал в #8.

Поэтому:

ibmieee.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef IBMIEEE_H
#define IBMIEEE_H
 
namespace ibmieee
{
 
#define CN_TYPE_NATIVE 0
#define CN_TYPE_XPORT 1
#define CN_TYPE_IEEEB 2
#define CN_TYPE_IEEEL 3
 
    int cnxptiee(unsigned char *from, int fromtype, unsigned char *to, int totype);
}
 
#endif
ibmieee.cpp
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
#include "ibmieee.h"
#include <memory.h>
 
namespace ibmieee
{
 
    void xpt2ieee(unsigned char *xport, unsigned char *ieee);
    void ieee2xpt(unsigned char *ieee, unsigned char *xport);
 
#ifndef FLOATREP
#define FLOATREP get_native()
    int get_native();
#endif
 
    /*-------------------------------------------------------------------*/
    /* rc = cnxptiee(from,fromtype,to,totype); */
    /* */
    /* where */
    /* */
    /* from pointer to a floating point value */
    /* fromtype type of floating point value (see below) */
    /* to pointer to target area */
    /* totype type of target value (see below) */
    /* */
    /* floating point types: */
    /* 0 native floating point */
    /* 1 IBM mainframe (transport representation) */
    /* 2 Big endian IEEE floating point */
    /* 3 Little endian IEEE floating point */
    /* */
    /* rc = cnxptiee(from,0,to,1); native -> transport */
    /* rc = cnxptiee(from,0,to,2); native -> Big endian IEEE */
    /* rc = cnxptiee(from,0,to,3); native -> Little endian IEEE */
    /* rc = cnxptiee(from,1,to,0); transport -> native */
    /* rc = cnxptiee(from,1,to,2); transport -> Big endian IEEE */
    /* rc = cnxptiee(from,1,to,3); transport -> Little endian IEEE */
    /* rc = cnxptiee(from,2,to,0); Big endian IEEE -> native */
    /* rc = cnxptiee(from,2,to,1); Big endian IEEE -> transport */
    /* rc = cnxptiee(from,2,to,3); Big endian IEEE -> Little endian IEEE */
    /* rc = cnxptiee(from,3,to,0); Little endian IEEE -> native */
    /* rc = cnxptiee(from,3,to,1); Little endian IEEE -> transport */
    /* rc = cnxptiee(from,3,to,2); Little endian IEEE -> Big endian IEEE */
    /*-------------------------------------------------------------------*/
 
    int cnxptiee(unsigned char *from, int fromtype, unsigned char *to, int totype) {
        unsigned char temp[8];
        int i;
        if (fromtype == CN_TYPE_NATIVE) {
            fromtype = FLOATREP;
        }
        switch (fromtype) {
            case CN_TYPE_IEEEL:
                if (totype == CN_TYPE_IEEEL)
                    break;
                for (i = 7; i >= 0; i--) {
                    temp[7 - i] = from[i];
                }
                from = temp;
                fromtype = CN_TYPE_IEEEB;
                /* break intentionally omitted */
            case CN_TYPE_IEEEB:
                /* break intentionally omitted */
            case CN_TYPE_XPORT:
                break;
            default:
                return(-1);
        }
        if (totype == CN_TYPE_NATIVE) {
            totype = FLOATREP;
        }
        switch (totype) {
            case CN_TYPE_XPORT:
            case CN_TYPE_IEEEB:
            case CN_TYPE_IEEEL:
                break;
            default:
                return(-2);
        }
        if (fromtype == totype) {
            memcpy(to, from, 8);
            return(0);
        }
        switch (fromtype) {
            case CN_TYPE_IEEEB:
                if (totype == CN_TYPE_XPORT)
                    ieee2xpt(from, to);
                else memcpy(to, from, 8);
                break;
            case CN_TYPE_XPORT:
                xpt2ieee(from, to);
                break;
        }
        if (totype == CN_TYPE_IEEEL) {
            memcpy(temp, to, 8);
            for (i = 7; i >= 0; i--) {
                to[7 - i] = temp[i];
            }
        }
        return(0);
    }
 
    int get_native() {
        static unsigned char float_reps[][8] = {
            {0x41,0x10,0x00,0x00,0x00,0x00,0x00,0x00},
            {0x3f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00},
            {0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f}
        };
        static double one = 1.00;
        int i, j;
        j = sizeof(float_reps) / 8;
        for (i = 0; i < j; i++) {
            if (memcmp(&one, float_reps + i, 8) == 0)
                return(i + 1);
        }
        return(-1);
    }
 
#ifdef BIG_ENDIAN
#define REVERSE(a,b)
#endif
 
#ifdef LITTLE_ENDIAN
#define DEFINE_REVERSE
    void REVERSE(void *, int);
#endif
 
#if !defined(DEFINE_REVERSE) && !defined(REVERSE)
#define DEFINE_REVERSE
    void REVERSE(void *, int);
#endif
 
    void xpt2ieee(unsigned char *xport, unsigned char *ieee) {
        unsigned char temp[8];
        int shift;
        int nib;
        unsigned long ieee1, ieee2;
        unsigned long xport1 = 0;
        unsigned long xport2 = 0;
        memcpy(temp, xport, 8);
        memset(ieee, 0, 8);
        if (*temp && memcmp(temp + 1, ieee, 7) == 0) {
            ieee[0] = ieee[1] = 0xff;
            ieee[2] = ~(*temp);
            return;
        }
        memcpy(((unsigned char *)&xport1) + sizeof(unsigned long) - 4, temp, 4);
        REVERSE(&xport1, sizeof(unsigned long));
        memcpy(((unsigned char *)&xport2) + sizeof(unsigned long) - 4, temp + 4, 4);
        REVERSE(&xport2, sizeof(unsigned long));
        /***************************************************************/
        /* Translate IBM format floating point numbers into IEEE */
        /* format floating point numbers. */
        /* */
        /* IEEE format: */
        /* */
        /* 6 5 0 */
        /* 3 1 0 */
        /* */
        /* SEEEEEEEEEEEMMMM ............ MMMM */
        /* */
        /* Sign bit, 11 bits exponent, 52 bit fraction. Exponent is */
        /* excess 1023. The fraction is multiplied by a power of 2 of */
        /* the actual exponent. Normalized floating point numbers are */
        /* represented with the binary point immediately to the left */
        /* of the fraction with an implied "1" to the left of the */
        /* binary point. */
        /* */
        /* IBM format: */
        /* */
        /* 6 5 0 */
        /* 3 1 0 */
        /* */
        /* SEEEEEEEMMMM ......... MMMM */
        /* */
        /* Sign bit, 7 bit exponent, 56 bit fraction. Exponent is */
        /* excess 64. The fraction is multiplied by a power of 16 of */
        /* the actual exponent. Normalized floating point numbers are */
        /* represented with the radix point immediately to the left of*/
        /* the high order hex fraction digit. */
        /* */
        /* How do you translate from IBM format to IEEE? */
        /* */
        /* Translating back to ieee format from ibm is easier than */
        /* going the other way. You lose at most, 3 bits of fraction, */
        /* but nothing can be done about that. The only tricky parts */
        /* are setting up the correct binary exponent from the ibm */
        /* hex exponent, and removing the implicit "1" bit of the ieee*/
        /* fraction (see vzctdbl). We must shift down the high order */
        /* nibble of the ibm fraction until it is 1. This is the */
        /* implicit 1. The bit is then cleared and the exponent */
        /* adjusted by the number of positions shifted. A more */
        /* thorough discussion is in vzctdbl.c. */
        /* Get the first half of the ibm number without the exponent */
        /* into the ieee number */
        ieee1 = xport1 & 0x00ffffff;
        /* get the second half of the ibm number into the second half */
        /* of the ieee number . If both halves were 0. then just */
        /* return since the ieee number is zero. */
        if ((!(ieee2 = xport2)) && !xport1)
            return;
        /* The fraction bit to the left of the binary point in the */
        /* ieee format was set and the number was shifted 0, 1, 2, or */
        /* 3 places. This will tell us how to adjust the ibm exponent */
        /* to be a power of 2 ieee exponent and how to shift the */
        /* fraction bits to restore the correct magnitude. */
        if ((nib = (int)xport1) & 0x00800000)
            shift = 3;
        else if (nib & 0x00400000)
            shift = 2;
        else if (nib & 0x00200000)
            shift = 1;
        else
            shift = 0;
        if (shift) {
            /* shift the ieee number down the correct number of places */
            /* then set the second half of the ieee number to be the */
            /* second half of the ibm number shifted appropriately, */
            /* ored with the bits from the first half that would have */
            /* been shifted in if we could shift a double. All we are */
            /* worried about are the low order 3 bits of the first */
            /* half since we're only shifting by 1, 2, or 3. */
            ieee1 >>= shift;
            ieee2 = (xport2 >> shift) |
                ((xport1 & 0x00000007) << (29 + (3 - shift)));
        }
        /* clear the 1 bit to the left of the binary point */
        ieee1 &= 0xffefffff;
        /* set the exponent of the ieee number to be the actual */
        /* exponent plus the shift count + 1023. Or this into the */
        /* first half of the ieee number. The ibm exponent is excess */
        /* 64 but is adjusted by 65 since during conversion to ibm */
        /* format the exponent is incremented by 1 and the fraction */
        /* bits left 4 positions to the right of the radix point. */
        ieee1 |= (((((long)(*temp & 0x7f) - 65) << 2) + shift + 1023) << 20) | (xport1 & 0x80000000);
        REVERSE(&ieee1, sizeof(unsigned long));
        memcpy(ieee, ((unsigned char *)&ieee1) + sizeof(unsigned long) - 4, 4);
        REVERSE(&ieee2, sizeof(unsigned long));
        memcpy(ieee + 4, ((unsigned char *)&ieee2) + sizeof(unsigned long) - 4, 4);
        return;
    }
    /*-------------------------------------------------------------*/
    /* Name: ieee2xpt */
    /* Purpose: converts IEEE to transport */
    /* Usage: rc = ieee2xpt(to_ieee,p_data); */
    /* Notes: this routine is an adaptation of the wzctdbl routine */
    /* from the Apollo. */
    /*-------------------------------------------------------------*/
 
 
    void ieee2xpt(unsigned char *ieee, unsigned char *xport)
        /* ieee ptr to IEEE field (2-8 bytes) */
        /* xport ptr to xport format (8 bytes) */
    {
        int shift;
        unsigned char misschar;
        int ieee_exp;
        unsigned long xport1, xport2;
        unsigned long ieee1 = 0;
        unsigned long ieee2 = 0;
        char ieee8[8];
        memcpy(ieee8, ieee, 8);
        /*------get 2 longs for shifting------------------------------*/
        memcpy(((unsigned char *)&ieee1) + sizeof(unsigned long) - 4, ieee8, 4);
        REVERSE(&ieee1, sizeof(unsigned long));
        memcpy(((unsigned char *)&ieee2) + sizeof(unsigned long) - 4, ieee8 + 4, 4);
        REVERSE(&ieee2, sizeof(unsigned long));
        memset(xport, 0, 8);
        /*-----if IEEE value is missing (1st 2 bytes are FFFF)-----*/
        if (*ieee8 == (char)0xff && ieee8[1] == (char)0xff) {
            misschar = ~ieee8[2];
            *xport = (misschar == 0xD2) ? 0x6D : misschar;
            return;
        }
 
        /**************************************************************/
        /* Translate IEEE floating point number into IBM format float */
        /* */
        /* IEEE format: */
        /* */
        /* 6 5 0 */
        /* 3 1 0 */
        /* */
        /* SEEEEEEEEEEEMMMM ........ MMMM */
        /* */
        /* Sign bit, 11 bit exponent, 52 fraction. Exponent is excess */
        /* 1023. The fraction is multiplied by a power of 2 of the */
        /* actual exponent. Normalized floating point numbers are */
        /* represented with the binary point immediately to the left */
        /* of the fraction with an implied "1" to the left of the */
        /* binary point. */
        /* */
        /* IBM format: */
        /* */
        /* 6 5 0 */
        /* 3 5 0 */
        /* */
        /* SEEEEEEEMMMM ......... MMMM */
        /* */
        /* Sign bit, 7 bit exponent, 56 bit fraction. Exponent is */
        /* excess 64. The fraction is multiplied by a power of 16 of */
        /* of the actual exponent. Normalized floating point numbers */
        /* are presented with the radix point immediately to the left */
        /* of the high order hex fraction digit. */
        /* */
        /* How do you translate from local to IBM format? */
        /* */
        /* The ieee format gives you a number that has a power of 2 */
        /* exponent and a fraction of the form "1.<fraction bits>". */
        /* The first step is to get that "1" bit back into the */
        /* fraction. Right shift it down 1 position, set the high */
        /* order bit and reduce the binary exponent by 1. Now we have */
        /* a fraction that looks like ".1<fraction bits>" and it's */
        /* ready to be shoved into ibm format. The ibm fraction has 4 */
        /* more bits than the ieee, the ieee fraction must therefore */
        /* be shifted left 4 positions before moving it in. We must */
        /* also correct the fraction bits to account for the loss of 2*/
        /* bits when converting from a binary exponent to a hex one */
        /* (>> 2). We must shift the fraction left for 0, 1, 2, or 3 */
        /* positions to maintain the proper magnitude. Doing */
        /* conversion this way would tend to lose bits in the fraction*/
        /* which is not desirable or necessary if we cheat a bit. */
        /* First of all, we know that we are going to have to shift */
        /* the ieee fraction left 4 places to put it in the right */
        /* position; we won't do that, we'll just leave it where it is*/
        /* and increment the ibm exponent by one, this will have the */
        /* same effect and we won't have to do any shifting. Now, */
        /* since we have 4 bits in front of the fraction to work with,*/
        /* we won't lose any bits. We set the bit to the left of the */
        /* fraction which is the implicit "1" in the ieee fraction. We*/
        /* then adjust the fraction to account for the loss of bits */
        /* when going to a hex exponent. This adjustment will never */
        /* involve shifting by more than 3 positions so no bits are */
        /* lost. */
 
        /* Get ieee number less the exponent into the first half of */
        /* the ibm number */
        xport1 = ieee1 & 0x000fffff;
 
        /* get the second half of the number into the second half of */
        /* the ibm number and see if both halves are 0. If so, ibm is */
        /* also 0 and we just return */
        if ((!(xport2 = ieee2)) && !ieee1) {
            ieee_exp = 0;
            goto doret;
        }
 
        /* get the actual exponent value out of the ieee number. The */
        /* ibm fraction is a power of 16 and the ieee fraction a power*/
        /* of 2 (16 ** n == 2 ** 4n). Save the low order 2 bits since */
        /* they will get lost when we divide the exponent by 4 (right */
        /* shift by 2) and we will have to shift the fraction by the */
        /* appropriate number of bits to keep the proper magnitude. */
        shift = (int)
            (ieee_exp = (int)(((ieee1 >> 16) & 0x7ff0) >> 4) - 1023) & 3;
 
        /* the ieee format has an implied "1" immdeiately to the left */
        /* of the binary point. Show it in here. */
        xport1 |= 0x00100000;
        if (shift) {
            /* set the first half of the ibm number by shifting it left */
            /* the appropriate number of bits and oring in the bits */
            /* from the lower half that would have been shifted in (if */
            /* we could shift a double). The shift count can never */
            /* exceed 3, so all we care about are the high order 3 */
            /* bits. We don't want sign extention so make sure it's an */
            /* unsigned char. We'll shift either5, 6, or 7 places to */
            /* keep 3, 2, or 1 bits. After that, shift the second half */
            /* of the number the right number of places. We always get */
            /* zero fill on left shifts. */
            xport1 = (xport1 << shift) |
                ((unsigned char)(((ieee2 >> 24) & 0xE0) >>
                (5 + (3 - shift))));
            xport2 <<= shift;
        }
 
        /* Now set the ibm exponent and the sign of the fraction. The */
        /* power of 2 ieee exponent must be divided by 4 and made */
        /* excess 64 (we add 65 here because of the poisition of the */
        /* fraction bits, essentially 4 positions lower than they */
        /* should be so we incrment the ibm exponent). */
        xport1 |= (((ieee_exp >> 2) + 65) | ((ieee1 >> 24) & 0x80)) << 24;
 
        /* If the ieee exponent is greater than 248 or less than -260, */
        /* then it cannot fit in the ibm exponent field. Send back the */
        /* appropriate flag. */
    doret:
        if (-260 <= ieee_exp && ieee_exp <= 248) {
            REVERSE(&xport1, sizeof(unsigned long));
            memcpy(xport, ((unsigned char *)&xport1) + sizeof(unsigned long) - 4, 4);
            REVERSE(&xport2, sizeof(unsigned long));
            memcpy(xport + 4, ((unsigned char *)&xport2) + sizeof(unsigned long) - 4, 4);
            return;
        }
        memset(xport, 0xFF, 8);
        if (ieee_exp > 248)
            *xport = 0x7f;
        return;
    }
 
#ifdef DEFINE_REVERSE
    void REVERSE(void *intpv, int l)
    {
        int i, j;
        char save;
        char *intp = (char *)intpv;
        static int one = 1;
#if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
        if (((unsigned char *)&one)[sizeof(one) - 1] == 1)
            return;
#endif
        j = l / 2;
        for (i = 0; i < j; i++) {
            save = intp[i];
            intp[i] = intp[l - i - 1];
            intp[l - i - 1] = save;
        }
    }
#endif
 
 
} // namespace ibmieee
main.cpp
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <iostream>
#include "ibmieee.h"
 
using namespace std;
 
#define N_TESTVALS 4
 
void tohex(unsigned char *bytes, char *hexchars, int length);
 
 
static unsigned char xpt_testvals[N_TESTVALS][8] = {
    {0x41,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, /* 1 */
    {0xc1,0x10,0x00,0x00,0x00,0x00,0x00,0x00}, /* -1 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* 0 */
    {0x41,0x20,0x00,0x00,0x00,0x00,0x00,0x00}  /* 2 */
};
 
static unsigned char ieeeb_testvals[N_TESTVALS][8] = {
    {0x3f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00}, /* 1 */
    {0xbf,0xf0,0x00,0x00,0x00,0x00,0x00,0x00}, /* -1 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* 0 */
    {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00}  /* 2 */
};
 
static unsigned char ieeel_testvals[N_TESTVALS][8] = {
    {0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f}, /* 1 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xbf}, /* -1 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* 0 */
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40}  /* 2 */
};
 
static double native[N_TESTVALS] = { 1,-1,0,2 };
 
#define N_MISSINGVALS 3
 
static unsigned char missingvals[N_MISSINGVALS][8] = {
    {0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* std missing */
    {0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* .A */
    {0x5A,0x00,0x00,0x00,0x00,0x00,0x00,0x00}  /* .Z */
};
 
/* rc = cnxptiee(from,0,to,1); native -> transport                   */
/* rc = cnxptiee(from,0,to,2); native -> Big endian IEEE             */
/* rc = cnxptiee(from,0,to,3); native -> Little endian IEEE          */
/* rc = cnxptiee(from,1,to,0); transport -> native                   */
/* rc = cnxptiee(from,1,to,2); transport -> Big endian IEEE          */
/* rc = cnxptiee(from,1,to,3); transport -> Little endian IEEE       */
/* rc = cnxptiee(from,2,to,0); Big endian IEEE -> native             */
/* rc = cnxptiee(from,2,to,1); Big endian IEEE -> transport          */
/* rc = cnxptiee(from,2,to,3); Big endian IEEE -> Little endian IEEE */
/* rc = cnxptiee(from,3,to,0); Little endian IEEE -> native          */
/* rc = cnxptiee(from,3,to,1); Little endian IEEE -> transport       */
/* rc = cnxptiee(from,3,to,2); Little endian IEEE -> Big endian IEEE */
 
int main() {
    unsigned char to[8];
    int i, matched;
 
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee((unsigned char *)&native[i], CN_TYPE_NATIVE, to, CN_TYPE_IEEEB);
        matched += (memcmp(to, ieeeb_testvals[i], 8) == 0);
    }
    printf("Native -> Big endian IEEE match count = %d (should be %d).\n", matched, N_TESTVALS);
 
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee((unsigned char *)&native[i], CN_TYPE_NATIVE, to, CN_TYPE_IEEEL);
        matched += (memcmp(to, ieeel_testvals[i], 8) == 0);
    }
    printf("Native -> Little endian IEEE match count = %d (should be %d).\n", matched, N_TESTVALS);
 
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee((unsigned char *)&native[i], CN_TYPE_NATIVE, to, CN_TYPE_XPORT);
        matched += (memcmp(to, xpt_testvals[i], 8) == 0);
    }
    printf("Native -> Transport match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(xpt_testvals[i], CN_TYPE_XPORT, to, CN_TYPE_IEEEB);
        matched += (memcmp(to, ieeeb_testvals[i], 8) == 0);
    }
    printf("Transport -> Big endian IEEE match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(xpt_testvals[i], CN_TYPE_XPORT, to, CN_TYPE_IEEEL);
        matched += (memcmp(to, ieeel_testvals[i], 8) == 0);
    }
    printf("Transport -> Little endian IEEE match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(xpt_testvals[i], CN_TYPE_XPORT, to, CN_TYPE_NATIVE);
        matched += (memcmp(to, &native[i], 8) == 0);
    }
    printf("Transport -> Native match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(ieeeb_testvals[i], CN_TYPE_IEEEB, to, CN_TYPE_IEEEL);
        matched += (memcmp(to, ieeel_testvals[i], 8) == 0);
    }
    printf("Big endian IEEE -> Little endian IEEE match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(ieeeb_testvals[i], CN_TYPE_IEEEB, to, CN_TYPE_XPORT);
        matched += (memcmp(to, xpt_testvals[i], 8) == 0);
    }
    printf("Big endian IEEE -> Transport match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(ieeeb_testvals[i], CN_TYPE_IEEEB, to, CN_TYPE_NATIVE);
        matched += (memcmp(to, &native[i], 8) == 0);
    }
    printf("Big endian IEEE -> Native match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(ieeel_testvals[i], CN_TYPE_IEEEL, to, CN_TYPE_IEEEB);
        matched += (memcmp(to, ieeeb_testvals[i], 8) == 0);
    }
    printf("Little endian IEEE -> Big endian IEEE match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(ieeel_testvals[i], CN_TYPE_IEEEL, to, CN_TYPE_XPORT);
        matched += (memcmp(to, xpt_testvals[i], 8) == 0);
    }
    printf("Little endian IEEE -> Transport match count = %d (should be %d).\n", matched, N_TESTVALS);
    for (i = matched = 0; i < N_TESTVALS; i++) {
        ibmieee::cnxptiee(ieeel_testvals[i], CN_TYPE_IEEEL, to, CN_TYPE_NATIVE);
        matched += (memcmp(to, &native[i], 8) == 0);
    }
    printf("Little endian IEEE -> Native match count = %d (should be %d).\n", matched, N_TESTVALS);
}
 
void tohex(unsigned char *bytes, char *hexchars, int length)
{
    static const char *hexdigits = "0123456789ABCDEF";
    for (int i = 0; i < length; i++) {
        *hexchars++ = hexdigits[*bytes >> 4];
        *hexchars++ = hexdigits[*bytes++ & 0x0f];
    }
    *hexchars = 0;
}
Итого, в проекте MSVS должно быть два файла в секции Source Files: main.cpp и ibmieee.cpp, и один файл в секции Header Files: ibmieee.h. Все три файла должны лежать рядом в каталоге проекта VS.

Я в подробности не вдавался, просто прошёлся напильником, что бы это был код на C++.

Компилируется (MS Visual Studio Community 2019, x64, проект в режиме совместимости с MS VS 2017) с уровнем предупреждений Level3 - без предупреждений.

Работает:
Code
1
2
3
4
5
6
7
8
9
10
11
12
Native -> Big endian IEEE match count = 4 (should be 4).
Native -> Little endian IEEE match count = 4 (should be 4).
Native -> Transport match count = 4 (should be 4).
Transport -> Big endian IEEE match count = 4 (should be 4).
Transport -> Little endian IEEE match count = 4 (should be 4).
Transport -> Native match count = 4 (should be 4).
Big endian IEEE -> Little endian IEEE match count = 4 (should be 4).
Big endian IEEE -> Transport match count = 4 (should be 4).
Big endian IEEE -> Native match count = 4 (should be 4).
Little endian IEEE -> Big endian IEEE match count = 4 (should be 4).
Little endian IEEE -> Transport match count = 4 (should be 4).
Little endian IEEE -> Native match count = 4 (should be 4).
Добавлено через 1 минуту
В другой проект тащите файлы ibmieee.h и ibmieee.cpp. Должно всё работать.
1
2 / 2 / 0
Регистрация: 08.01.2016
Сообщений: 491
26.01.2020, 18:52  [ТС]
L0M, спасибо большое!
так как Вы написали все работает
пытаюсь теперь подстроить код под свою задачу
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.01.2020, 18:52
Помогаю со студенческими работами здесь

Чем отличаются float преобразования (float)var от float(var)
Здравствуйте! Подскажите, чем отличается (float)var от float(var)

Конвертация типов. float в string/char
Помогите реализовать! Для примера возьмем: У меня есть двумерный массив типа float (Primer1) и есть массив типа string или char...

Не происходит конвертация типа int в float
int r = 130; r = (float)r/255; r равен 0. Почему не произошла конвертация типа?

invalid types `float[float]' for array subscript
void SEARCH(float vol, float price, int i) { if (i&gt;N) { if(price&gt;maxprice) { ...

Неправильное приведение void* к *float а далее к float
Почему когда привожу void* к int* потом к int то все работает, данные не бьются и работают нормально, когда делаю те же операции но с...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru