Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/network/converter.cc @ 6740

Last change on this file since 6740 was 6737, checked in by patrick, 19 years ago

trunk: merged network back to trunk

File size: 12.9 KB
RevLine 
[6106]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"
[6634]24#include "shell_command.h"
[6106]25
[6634]26#include <limits>
[6106]27
[6634]28SHELL_COMMAND_STATIC(debug, Converter, Converter::debug);
29
30
[6106]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
[6341]61
62
[6106]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  }
[6341]72
[6106]73  for (int i = 0; i < INTSIZE; i++)
74  {
75    result[i] = x % mod;
76    x /= mod;
77  }
[6341]78
[6106]79  if (sgn == -1)
80    result[INTSIZE - 1] += sgnadd;
[6341]81
82
[6106]83  return result;
84}
85
86/*!
[6341]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
[6737]90 * @return: The number of written bytes
[6341]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/*!
[6106]124 * Converts a byte-array into an int
125 * @param a: The byte-array which is to convert
[6737]126 * @param x: The place where the result is stored
127 * @return: The number of read bytes
[6106]128 */
[6341]129int Converter::byteArrayToInt(const byte* a, int* x)
[6106]130{
131  int mult = 1;
132  const int step = 256; // = 2 ^ 8
[6341]133  *x = 0;
[6108]134  for (int i = 0; i < INTSIZE - 1; i++)
[6106]135  {
[6341]136    *x += a[i] * mult;
[6106]137    mult *= step;
138  }
[6341]139
[6108]140  if (a[INTSIZE - 1] >= sgnadd)
[6106]141  {
[6341]142    *x += (a[INTSIZE - 1] - sgnadd) * mult;
143    *x *= -1;
[6106]144  }
145  else
[6341]146    *x += a[INTSIZE - 1] * mult;
147
148  return INTSIZE;
[6106]149}
[6128]150
[6341]151/*!
152 * Converts a float into a string containing its binary representation
[6737]153 * @param x: The float which is to convert
154 * @return: A string containing the float's binary representation
[6341]155 */
156char* Converter::floatToBinString(float x)
[6128]157{
158  char* result = new char[200];
159  int pos = 0;
[6341]160
161  if (x < 0)
[6128]162  {
[6341]163    result[pos++] = '-';
164    x = -x;
[6128]165  }
[6341]166
167  float sub = 1;
168  while (sub < x)
169    sub *= 2;
170
171  while ((x > 0 || sub >= 1) && pos < 200)
[6128]172  {
173    if (x >= sub)
174    {
175      result[pos] = '1';
176      x -= sub;
177    }
178    else
179      result[pos] = '0';
180    pos++;
181    sub /= 2;
[6341]182
183    if (sub == 0.5f)
184      result[pos++] = '.';
[6128]185  }
[6341]186
[6128]187  return result;
[6341]188}
[6128]189
[6341]190const int expmult = 8388608; //2^23
191
[6634]192float Converter::getDenormConst()
193{
194  const int exp = 126;
195  float result = 1.0f;
196  for (int i = 0; i < exp; i++)
197    result /= 2.0f;
198  return result;
199}
200
[6341]201/*!
202 * Converts a float value into a byte-array
203 * @param x: The float which is to convert
204 * @return: A byte-array which accords the given float
205 */
206byte* Converter::floatToByteArray(float x)
[6128]207{
[6634]208  byte* result = new byte[4];
209  floatToByteArray(x, result, 4);
210  return result;
211  /*
[6341]212  int mantisse = 0;
213  int exponent = 128;
214
215  int sgn;
216  if (x < 0)
217  {
218    x = -x;
219    sgn = -1;
220  }
221  else
222    sgn = 1;
223
[6634]224  if (x == 0)
[6341]225  {
[6634]226    exponent = 255;
227    mantisse = 0;
[6341]228  }
[6634]229  else
230  {
231    //if (x < getDenormConst())
232    //  printf("Denormalisiert!\n");
233    //printf("DenormConst = %e", getDenormConst());
[6341]234
[6634]235    float sub = 1;
236    while (sub < x)
[6128]237    {
[6634]238      sub *= 2;
239      exponent++;
[6128]240    }
[6341]241
[6634]242    while (x > 0)
243    {
244      if (x >= sub)
245      {
246        mantisse += 1;
247        x -= sub;
248      }
249
250      mantisse *= 2;
251      exponent--;
252      sub /= 2;
253    }
254    exponent++;
255    mantisse /= 2;
256
257    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
258
259
260    if (mantisse != 0)
261    {
262      while (mantisse < expmult)
263      {
264        mantisse *= 2;
265        exponent--;
266      }
267
268      mantisse -= expmult;
269    }
[6128]270  }
[6341]271
[6634]272  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]273
274
275  int hx = mantisse + expmult * exponent;
276  byte* result = intToByteArray(hx);
277  if (sgn == -1)
278    result[3] += sgnadd;
279
280  return result;
[6634]281  */
[6341]282}
283
284
285/*!
286 * Converts a byte-array into a float value
287 * @param a: The byte-array which is to convert
288 * @return: A float value which accords the given byte-array
289 */
290float Converter::byteArrayToFloat(byte* a)
291{
[6634]292  byte* h = new byte[4];
293  float result = 0.0f;
294  byteArrayToFloat(a, &result);
295  return result;
296  /*
297  int hexp = a[2] + a[3] * 256;
298  int exponent = (hexp / 128) % 256;
299
[6341]300  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
301  int mantisse = hmant % expmult;
[6634]302  if (mantisse == 0 && exponent == 255)
303    return 0;
304
[6341]305  mantisse += expmult;
[6634]306  exponent -= 128;
[6341]307
308
309  int sgn;
310  if (a[3] >= sgnadd)
311    sgn = -1;
312  else
313    sgn = 1;
314
[6634]315  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]316
317  float emult = 1;
318  if (exponent > 0)
319    for (int i = 0; i < exponent; i++)
320      emult *= 2;
321  else if (exponent < 0)
322    for (int i = 0; i > exponent; i--)
323      emult /= 2;
324
325  float result = mantisse * emult;
326  if (sgn == -1)
327    result = -result;
328
329  return result;
[6634]330  */
[6341]331}
332
333/*!
334 * Converts a float value into a byte-array and stores the result into a given byte-array
335 * @param x: The float which is to convert
[6737]336 * @param a: The byte array where the result is to store
337 * @param length: The length of the array a
338 * @return: The number of written bytes
[6341]339 */
[6737]340int Converter::floatToByteArray(float x, byte* a, int length)
[6341]341{
342  if (length < FLOATSIZE)
343  {
344    PRINTF(1)("byte buffer to short to store a float. Needed length %i. Avaiable length %i", FLOATSIZE, length);
345    return -1;
346  }
347
348  //handle 0 else function will loop for ever
[6634]349  /*if ( x == 0 )
[6341]350  {
351    for ( int i = 0; i<FLOATSIZE; i++)
352      a[i] = 0;
353    return FLOATSIZE;
[6634]354}*/
[6341]355
356  int mantisse = 0;
357  int exponent = 128;
358
359  int sgn;
360  if (x < 0)
361  {
362    x = -x;
363    sgn = -1;
364  }
365  else
366    sgn = 1;
367
[6634]368  if (x == 0)
[6341]369  {
[6634]370    exponent = 255;
371    mantisse = 0;
[6341]372  }
[6634]373  else
374  {
375    //if (x < getDenormConst())
376    //  printf("Denormalisiert!\n");
377    //printf("DenormConst = %e", getDenormConst());
[6341]378
[6634]379    float sub = 1;
380    while (sub < x)
[6128]381    {
[6634]382      sub *= 2;
383      exponent++;
[6128]384    }
[6341]385
[6634]386    while (x > 0)
387    {
388      if (x >= sub)
389      {
390        mantisse += 1;
391        x -= sub;
392      }
393
394      mantisse *= 2;
395      exponent--;
396      sub /= 2;
397    }
398    exponent++;
399    mantisse /= 2;
400
401
402///    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
403
404
[6737]405    //if (mantisse != 0)
406    //{
[6634]407      while (mantisse < expmult)
408      {
409        mantisse *= 2;
410        exponent--;
411      }
412
[6737]413      if (exponent >= 0)
414        mantisse -= expmult;
415      else
416      {
417        //Denormalized
418        while (exponent < 0)
419        {
420          mantisse /= 2;
421          exponent++;
422        }
423        printf("Conv: Denorm");
424      }
425    //}
[6128]426  }
[6341]427
[6634]428///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]429
430
431  int hx = mantisse + expmult * exponent;
[6737]432  //int result = intToByteArray(hx, a, length);
433  intToByteArray(hx, a, length);
[6341]434  if (sgn == -1)
435    a[3] += sgnadd;
436
[6634]437
438//  int hx = mantisse + expmult * exponent;
439//  byte* result = intToByteArray(hx);
440//  if (sgn == -1)
441//    result[3] += sgnadd;
442
[6737]443  //return result;
444  return FLOATSIZE;
[6128]445}
[6341]446
447
448/*!
449 * Converts a byte-array into a float value
450 * @param a: The byte-array which is to convert
[6737]451 * @param x: The place where the result is to store
452 * @return: The number of read bytes
[6341]453 */
[6737]454int Converter::byteArrayToFloat(const byte* a, float* x)
[6341]455{
[6634]456    //handle 0
457  /*for (int i = 0; i<FLOATSIZE; i++)
[6341]458  {
459    if (a[i]!=0)
460      break;
461    if ( i==FLOATSIZE-1 )
462    {
463      *x = 0.0f;
464      return FLOATSIZE;
465    }
[6634]466}*/
[6341]467
[6634]468  int hexp = a[2] + a[3] * 256;
469  int exponent = (hexp / 128) % 256;
[6341]470
471  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
472  int mantisse = hmant % expmult;
[6634]473
474  //handle 0
475  if (mantisse == 0 && exponent == 255)
476  {
477    *x = 0;
478    return FLOATSIZE;
479  }
[6737]480  else if (exponent == 0 && mantisse != 0)
481  {
482    exponent = -126;
483    printf("ReConv: Denorm");
484  }
485  else
486  {
487    mantisse += expmult;
488    exponent -= 128;
489  }
[6634]490
[6341]491  int sgn;
492  if (a[3] >= sgnadd)
493    sgn = -1;
494  else
495    sgn = 1;
496
[6634]497///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]498
499  float emult = 1;
500  if (exponent > 0)
501    for (int i = 0; i < exponent; i++)
502      emult *= 2;
503  else if (exponent < 0)
504    for (int i = 0; i > exponent; i--)
505      emult /= 2;
506
[6634]507  /*
508  float result = mantisse * emult;
509  if (sgn == -1)
510    result = -result;
511
512  return result;
513  */
514
[6341]515  *x = mantisse * emult;
516  if (sgn == -1)
517    *x = -  *x;
518
519  return FLOATSIZE;
520}
521
[6634]522/*!
523 * Converts a float value into a byte-array
524 * @param x: The float which is to convert
[6737]525 * @param a: The array where the result is to store
526 * @param length: The length of the array a
527 * @return: The number of written bytes
[6634]528 */
[6737]529int Converter::_floatToByteArray(float x, byte* a, int length)
[6634]530{
[6737]531  if ( length< FLOATSIZE )
[6634]532  {
533    PRINTF(1)("Byte Array to small\n");
534    return 0;
535  }
536  byte* p = (byte*)&x;
537
538  for (int i = 0; i < 4; i++)
539    a[i] = p[i];
[6737]540 
541  return FLOATSIZE;
[6634]542}
543
544
545/*!
546 * Converts a byte-array into a float value
547 * @param a: The byte-array which is to convert
[6737]548 * @param x: The place where the result is to store
549 * @return: The number of read bytes
[6634]550 */
[6737]551int Converter::_byteArrayToFloat(const byte* a, float* x)
[6634]552{
553  *x = *((float*)a);
554
[6737]555  return FLOATSIZE;
[6634]556}
557
[6737]558
559
560
561
562
563
564
565
566
[6341]567/**
568 * copies a strint to a byte array
569 * @param s: string to copy
570 * @param a: byte array
571 * @param length: string length
572 * @return: the used number of bytes in byte array
573 */
574int Converter::stringToByteArray( const char * s, byte * a, int length, int maxLength )
575{
576  if ( length+INTSIZE > maxLength )
577  {
578    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, length+INTSIZE);
579    return -1;
580  }
581
582  int n = Converter::intToByteArray( length, a, maxLength );
583
584  memcpy( a+INTSIZE, s, length );
585
586  return length + INTSIZE;
587}
588
589/**
590 * reads a string out of a byte array
591 * @param a: byte array
592 * @param s: string
593 * @param maxLength: max bytes to copy
594 * @return: the number of read bytes in byte array
595 */
596int Converter::byteArrayToString( const byte * a, char * s, int maxLength )
597{
598  int length;
599
600  int n = Converter::byteArrayToInt( a, &length );
601
602
603  if ( length+1 > maxLength )
604  {
605    PRINTF(1)("There is not enough space in string (%d) to store %d bytes\n", maxLength, length+1 );
606    strncpy(s,"",maxLength);
607    return -1;
608  }
609
610  memcpy( s, a+n, length );
611  s[length] = '\0';
612
613  return n+length;
614}
615
616/**
617 * reads a string out of a byte array and allocates memory for string
618 * @param a: byte array
619 * @param s: string
620 * @param maxLength: max bytes to copy
621 * @return: the number of read bytes in byte array
622 */
623int Converter::byteArrayToStringM( const byte * a, char*& s )
624{
625  int length;
626
627  int n = Converter::byteArrayToInt( a, &length );
628
629  s = new char[length+1];
630
631  if ( !s )
632  {
633    PRINTF(1)("Could not allocate memory!\n" );
634    return -1;
635  }
636
637  memcpy( s, a+n, length );
638  s[length] = '\0';
639
640  return n+length;
641}
642
[6634]643
644
645
646void Converter::floatTest(float x)
647{
648  //float x = 8.0f;
649  //float x = numeric_limits<float>::infinity();
650
651  printf("To Convert: %e\n", x);
652
653  byte* res = floatToByteArray(x);
654  for (int i = 0; i < 4; i++)
655    printf("%i ", res[i]);
656  printf("\n");
657
658  float y = byteArrayToFloat(res);
659  printf("ReConvert: %e\n", y);
660
661  if (x == y)
662    printf("equal\n");
663  else
664    printf("different\n");
665}
666
[6737]667void Converter::ArrayfloatTest(float x)
668{
669  //float x = 8.0f;
670  //float x = numeric_limits<float>::infinity();
671
672  printf("To Convert: %e\n", x);
673  byte* res = new byte[4];
674
675  int wr = floatToByteArray(x, res, 4);
676  for (int i = 0; i < 4; i++)
677    printf("%i ", res[i]);
678  printf("  written bytes: %i \n", wr);
679
680  float y;
681  int rd = byteArrayToFloat(res, &y);
682  printf("ReConvert: %e\n", y);
683  printf("Read bytes: %i   ->  ", rd);
684
685  if (x == y)
686    printf("equal\n");
687  else
688    printf("different\n");
689}
690
[6634]691void Converter::debug()
692{
693  printf("We rulez\n");
694
[6737]695  ArrayfloatTest(0.125f);
696  ArrayfloatTest(64.0f);
697  ArrayfloatTest(0.0f);
698  ArrayfloatTest(5.00091e-29f);
[6634]699
700  //floatTest(-18.0098f);
701  //floatTest(-24.07e23f);
702  //floatTest(-0.0f);
703  //floatTest(-5.67e-29f);
[6737]704 
705 
706  //floatTest(-45.7e-32f);
707  //floatTest(45.7e-33f);
708  //floatTest(-45.7e-34f);
709  //floatTest(45.7e-35f);
[6634]710}
Note: See TracBrowser for help on using the repository browser.