Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/lib/network/converter.cc @ 6573

Last change on this file since 6573 was 6573, checked in by rennerc, 18 years ago
File size: 11.7 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Benjamin Wuest
13   co-programmer: ...
14*/
15
16
17/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
18   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
19*/
20#define DEBUG_MODULE_NETWORK
21
22/* include your own header */
23#include "converter.h"
24#include "shell_command.h"
25
26#include <limits>
27
28SHELL_COMMAND_STATIC(debug, Converter, Converter::debug);
29
30
31/* using namespace std is default, this needs to be here */
32using namespace std;
33
34/*!
35 * Standard constructor
36 */
37Converter::Converter()
38{
39  /* set the class id for the base object */
40  //this->setClassID(CL_ENTITY_MANAGER, "EntityManager");
41}
42
43/*!
44 * Standard destructor
45 */
46Converter::~Converter()
47{
48}
49
50const int sgnadd = 128; // = 2^7
51
52/*!
53 * Converts an int into a byte-array
54 * @remarks: The int is stored in big-endian
55 * @param x: The int which is to convert
56 * @return: A byte-array that accords the given int value
57 */
58byte* Converter::intToByteArray(int x)
59{
60  const int mod = 256; // = 2^8
61
62
63  byte* result = new byte[INTSIZE];
64  int sgn;
65  if (x >= 0)
66    sgn = 1;
67  else
68  {
69    sgn = -1;
70    x = -x;
71  }
72
73  for (int i = 0; i < INTSIZE; i++)
74  {
75    result[i] = x % mod;
76    x /= mod;
77  }
78
79  if (sgn == -1)
80    result[INTSIZE - 1] += sgnadd;
81
82
83  return result;
84}
85
86/*!
87 * Converts an int into a byte-array and stores the result into a given byte-array
88 * @remarks: The int is stored in big-endian
89 * @param x: The int which is to convert
90 * @return: A byte-array that accords the given int value
91 */
92int Converter::intToByteArray(int x, byte* a, int length)
93{
94  if (length < INTSIZE)
95  {
96    PRINTF(1)("byte buffer to short to store an int. Needed length %i. Avaiable length %i", INTSIZE, length);
97    return -1;
98  }
99
100  const int mod = 256; // = 2^8
101
102  int sgn;
103  if (x >= 0)
104    sgn = 1;
105  else
106  {
107    sgn = -1;
108    x = -x;
109  }
110
111  for (int i = 0; i < INTSIZE; i++)
112  {
113    a[i] = x % mod;
114    x /= mod;
115  }
116
117  if (sgn == -1)
118    a[INTSIZE - 1] += sgnadd;
119
120  return INTSIZE;
121}
122
123/*!
124 * Converts a byte-array into an int
125 * @param a: The byte-array which is to convert
126 * @return: An int that accords the given byte-array
127 */
128int Converter::byteArrayToInt(const byte* a, int* x)
129{
130  int mult = 1;
131  const int step = 256; // = 2 ^ 8
132  *x = 0;
133  for (int i = 0; i < INTSIZE - 1; i++)
134  {
135    *x += a[i] * mult;
136    mult *= step;
137  }
138
139  if (a[INTSIZE - 1] >= sgnadd)
140  {
141    *x += (a[INTSIZE - 1] - sgnadd) * mult;
142    *x *= -1;
143  }
144  else
145    *x += a[INTSIZE - 1] * mult;
146
147  return INTSIZE;
148}
149
150/*!
151 * Converts a float into a string containing its binary representation
152 */
153char* Converter::floatToBinString(float x)
154{
155  char* result = new char[200];
156  int pos = 0;
157
158  if (x < 0)
159  {
160    result[pos++] = '-';
161    x = -x;
162  }
163
164  float sub = 1;
165  while (sub < x)
166    sub *= 2;
167
168  while ((x > 0 || sub >= 1) && pos < 200)
169  {
170    if (x >= sub)
171    {
172      result[pos] = '1';
173      x -= sub;
174    }
175    else
176      result[pos] = '0';
177    pos++;
178    sub /= 2;
179
180    if (sub == 0.5f)
181      result[pos++] = '.';
182  }
183
184  return result;
185}
186
187const int expmult = 8388608; //2^23
188
189float Converter::getDenormConst()
190{
191  const int exp = 126;
192  float result = 1.0f;
193  for (int i = 0; i < exp; i++)
194    result /= 2.0f;
195  return result;
196}
197
198/*!
199 * Converts a float value into a byte-array
200 * @param x: The float which is to convert
201 * @return: A byte-array which accords the given float
202 */
203byte* Converter::floatToByteArray(float x)
204{
205  byte* result = new byte[4];
206  floatToByteArray(x, result, 4);
207  return result;
208  /*
209  int mantisse = 0;
210  int exponent = 128;
211
212  int sgn;
213  if (x < 0)
214  {
215    x = -x;
216    sgn = -1;
217  }
218  else
219    sgn = 1;
220
221  if (x == 0)
222  {
223    exponent = 255;
224    mantisse = 0;
225  }
226  else
227  {
228    //if (x < getDenormConst())
229    //  printf("Denormalisiert!\n");
230    //printf("DenormConst = %e", getDenormConst());
231
232    float sub = 1;
233    while (sub < x)
234    {
235      sub *= 2;
236      exponent++;
237    }
238
239    while (x > 0)
240    {
241      if (x >= sub)
242      {
243        mantisse += 1;
244        x -= sub;
245      }
246
247      mantisse *= 2;
248      exponent--;
249      sub /= 2;
250    }
251    exponent++;
252    mantisse /= 2;
253
254    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
255
256
257    if (mantisse != 0)
258    {
259      while (mantisse < expmult)
260      {
261        mantisse *= 2;
262        exponent--;
263      }
264
265      mantisse -= expmult;
266    }
267  }
268
269  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
270
271
272  int hx = mantisse + expmult * exponent;
273  byte* result = intToByteArray(hx);
274  if (sgn == -1)
275    result[3] += sgnadd;
276
277  return result;
278  */
279}
280
281
282/*!
283 * Converts a byte-array into a float value
284 * @param a: The byte-array which is to convert
285 * @return: A float value which accords the given byte-array
286 */
287float Converter::byteArrayToFloat(byte* a)
288{
289  byte* h = new byte[4];
290  float result = 0.0f;
291  byteArrayToFloat(a, &result);
292  return result;
293  /*
294  int hexp = a[2] + a[3] * 256;
295  int exponent = (hexp / 128) % 256;
296
297  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
298  int mantisse = hmant % expmult;
299  if (mantisse == 0 && exponent == 255)
300    return 0;
301
302  mantisse += expmult;
303  exponent -= 128;
304
305
306  int sgn;
307  if (a[3] >= sgnadd)
308    sgn = -1;
309  else
310    sgn = 1;
311
312  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
313
314  float emult = 1;
315  if (exponent > 0)
316    for (int i = 0; i < exponent; i++)
317      emult *= 2;
318  else if (exponent < 0)
319    for (int i = 0; i > exponent; i--)
320      emult /= 2;
321
322  float result = mantisse * emult;
323  if (sgn == -1)
324    result = -result;
325
326  return result;
327  */
328}
329
330/*!
331 * Converts a float value into a byte-array and stores the result into a given byte-array
332 * @param x: The float which is to convert
333 * @return: A byte-array which accords the given float
334 */
335int Converter::floatToByteArray(float x, byte* a, int length)
336{
337  if (length < FLOATSIZE)
338  {
339    PRINTF(1)("byte buffer to short to store a float. Needed length %i. Avaiable length %i", FLOATSIZE, length);
340    return -1;
341  }
342
343  //handle 0 else function will loop for ever
344  /*if ( x == 0 )
345  {
346    for ( int i = 0; i<FLOATSIZE; i++)
347      a[i] = 0;
348    return FLOATSIZE;
349}*/
350
351  int mantisse = 0;
352  int exponent = 128;
353
354  int sgn;
355  if (x < 0)
356  {
357    x = -x;
358    sgn = -1;
359  }
360  else
361    sgn = 1;
362
363  if (x == 0)
364  {
365    exponent = 255;
366    mantisse = 0;
367  }
368  else
369  {
370    //if (x < getDenormConst())
371    //  printf("Denormalisiert!\n");
372    //printf("DenormConst = %e", getDenormConst());
373
374    float sub = 1;
375    while (sub < x)
376    {
377      sub *= 2;
378      exponent++;
379    }
380
381    while (x > 0)
382    {
383      if (x >= sub)
384      {
385        mantisse += 1;
386        x -= sub;
387      }
388
389      mantisse *= 2;
390      exponent--;
391      sub /= 2;
392    }
393    exponent++;
394    mantisse /= 2;
395
396
397///    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
398
399
400    if (mantisse != 0)
401    {
402      while (mantisse < expmult)
403      {
404        mantisse *= 2;
405        exponent--;
406      }
407
408      mantisse -= expmult;
409    }
410  }
411
412///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
413
414
415  int hx = mantisse + expmult * exponent;
416  int result = intToByteArray(hx, a, length);
417  if (sgn == -1)
418    a[3] += sgnadd;
419
420
421//  int hx = mantisse + expmult * exponent;
422//  byte* result = intToByteArray(hx);
423//  if (sgn == -1)
424//    result[3] += sgnadd;
425
426  return result;
427}
428
429
430/*!
431 * Converts a byte-array into a float value
432 * @param a: The byte-array which is to convert
433 * @return: A float value which accords the given byte-array
434 */
435int Converter::byteArrayToFloat(const byte* a, float* x)
436{
437    //handle 0
438  /*for (int i = 0; i<FLOATSIZE; i++)
439  {
440    if (a[i]!=0)
441      break;
442    if ( i==FLOATSIZE-1 )
443    {
444      *x = 0.0f;
445      return FLOATSIZE;
446    }
447}*/
448
449  int hexp = a[2] + a[3] * 256;
450  int exponent = (hexp / 128) % 256;
451
452  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
453  int mantisse = hmant % expmult;
454
455  //handle 0
456  if (mantisse == 0 && exponent == 255)
457    return 0;
458
459  mantisse += expmult;
460  exponent -= 128;
461
462
463  int sgn;
464  if (a[3] >= sgnadd)
465    sgn = -1;
466  else
467    sgn = 1;
468
469///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
470
471  float emult = 1;
472  if (exponent > 0)
473    for (int i = 0; i < exponent; i++)
474      emult *= 2;
475  else if (exponent < 0)
476    for (int i = 0; i > exponent; i--)
477      emult /= 2;
478
479  /*
480  float result = mantisse * emult;
481  if (sgn == -1)
482    result = -result;
483
484  return result;
485  */
486
487  *x = mantisse * emult;
488  if (sgn == -1)
489    *x = -  *x;
490
491  return FLOATSIZE;
492}
493
494/*!
495 * Converts a float value into a byte-array
496 * @param x: The float which is to convert
497 * @return: A byte-array which accords the given float
498 */
499byte* Converter::_floatToByteArray(float x)
500{
501  byte* p = (byte*)&x;
502  byte* result = new byte[4];
503  for (int i = 0; i < 4; i++)
504    result[i] = p[i];
505  return result;
506}
507
508
509/*!
510 * Converts a byte-array into a float value
511 * @param a: The byte-array which is to convert
512 * @return: A float value which accords the given byte-array
513 */
514float Converter::_byteArrayToFloat(byte* a)
515{
516  float* p = (float*)a;
517  float result = *p;
518  return result;
519}
520
521/**
522 * copies a strint to a byte array
523 * @param s: string to copy
524 * @param a: byte array
525 * @param length: string length
526 * @return: the used number of bytes in byte array
527 */
528int Converter::stringToByteArray( const char * s, byte * a, int length, int maxLength )
529{
530  if ( length+INTSIZE > maxLength )
531  {
532    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, length+INTSIZE);
533    return -1;
534  }
535
536  int n = Converter::intToByteArray( length, a, maxLength );
537
538  memcpy( a+INTSIZE, s, length );
539
540  return length + INTSIZE;
541}
542
543/**
544 * reads a string out of a byte array
545 * @param a: byte array
546 * @param s: string
547 * @param maxLength: max bytes to copy
548 * @return: the number of read bytes in byte array
549 */
550int Converter::byteArrayToString( const byte * a, char * s, int maxLength )
551{
552  int length;
553
554  int n = Converter::byteArrayToInt( a, &length );
555
556
557  if ( length+1 > maxLength )
558  {
559    PRINTF(1)("There is not enough space in string (%d) to store %d bytes\n", maxLength, length+1 );
560    strncpy(s,"",maxLength);
561    return -1;
562  }
563
564  memcpy( s, a+n, length );
565  s[length] = '\0';
566
567  return n+length;
568}
569
570/**
571 * reads a string out of a byte array and allocates memory for string
572 * @param a: byte array
573 * @param s: string
574 * @param maxLength: max bytes to copy
575 * @return: the number of read bytes in byte array
576 */
577int Converter::byteArrayToStringM( const byte * a, char*& s )
578{
579  int length;
580
581  int n = Converter::byteArrayToInt( a, &length );
582
583  s = new char[length+1];
584
585  if ( !s )
586  {
587    PRINTF(1)("Could not allocate memory!\n" );
588    return -1;
589  }
590
591  memcpy( s, a+n, length );
592  s[length] = '\0';
593
594  return n+length;
595}
596
597
598
599
600void Converter::floatTest(float x)
601{
602  //float x = 8.0f;
603  //float x = numeric_limits<float>::infinity();
604
605  printf("To Convert: %e\n", x);
606
607  byte* res = floatToByteArray(x);
608  for (int i = 0; i < 4; i++)
609    printf("%i ", res[i]);
610  printf("\n");
611
612  float y = byteArrayToFloat(res);
613  printf("ReConvert: %e\n", y);
614
615  if (x == y)
616    printf("equal\n");
617  else
618    printf("different\n");
619}
620
621void Converter::debug()
622{
623  printf("We rulez\n");
624
625  //Denormalized?
626  //floatTest(-9.87624e-38f);
627  //floatTest(-9.87624e-37f);
628  //floatTest(-9.87624e-36f);
629  //floatTest(-9.87624e-35f);
630
631  /*
632  floatTest(14.7f);
633  floatTest(12.07e15f);
634  floatTest(0.0f);
635  floatTest(5.67e-15f);
636  */
637
638  //floatTest(-18.0098f);
639  //floatTest(-24.07e23f);
640  //floatTest(-0.0f);
641  //floatTest(-5.67e-29f);
642  floatTest(-45.7e-32f);
643  floatTest(45.7e-33f);
644  floatTest(-45.7e-34f);
645  floatTest(45.7e-35f);
646}
Note: See TracBrowser for help on using the repository browser.