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
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: The number of written bytes
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 * @param x: The place where the result is stored
127 * @return: The number of read bytes
128 */
129int Converter::byteArrayToInt(const byte* a, int* x)
130{
131  int mult = 1;
132  const int step = 256; // = 2 ^ 8
133  *x = 0;
134  for (int i = 0; i < INTSIZE - 1; i++)
135  {
136    *x += a[i] * mult;
137    mult *= step;
138  }
139
140  if (a[INTSIZE - 1] >= sgnadd)
141  {
142    *x += (a[INTSIZE - 1] - sgnadd) * mult;
143    *x *= -1;
144  }
145  else
146    *x += a[INTSIZE - 1] * mult;
147
148  return INTSIZE;
149}
150
151/*!
152 * Converts a float into a string containing its binary representation
153 * @param x: The float which is to convert
154 * @return: A string containing the float's binary representation
155 */
156char* Converter::floatToBinString(float x)
157{
158  char* result = new char[200];
159  int pos = 0;
160
161  if (x < 0)
162  {
163    result[pos++] = '-';
164    x = -x;
165  }
166
167  float sub = 1;
168  while (sub < x)
169    sub *= 2;
170
171  while ((x > 0 || sub >= 1) && pos < 200)
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;
182
183    if (sub == 0.5f)
184      result[pos++] = '.';
185  }
186
187  return result;
188}
189
190const int expmult = 8388608; //2^23
191
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
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)
207{
208  byte* result = new byte[4];
209  floatToByteArray(x, result, 4);
210  return result;
211  /*
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
224  if (x == 0)
225  {
226    exponent = 255;
227    mantisse = 0;
228  }
229  else
230  {
231    //if (x < getDenormConst())
232    //  printf("Denormalisiert!\n");
233    //printf("DenormConst = %e", getDenormConst());
234
235    float sub = 1;
236    while (sub < x)
237    {
238      sub *= 2;
239      exponent++;
240    }
241
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    }
270  }
271
272  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
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;
281  */
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{
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
300  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
301  int mantisse = hmant % expmult;
302  if (mantisse == 0 && exponent == 255)
303    return 0;
304
305  mantisse += expmult;
306  exponent -= 128;
307
308
309  int sgn;
310  if (a[3] >= sgnadd)
311    sgn = -1;
312  else
313    sgn = 1;
314
315  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
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;
330  */
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
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
339 */
340int Converter::floatToByteArray(float x, byte* a, int length)
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
349  /*if ( x == 0 )
350  {
351    for ( int i = 0; i<FLOATSIZE; i++)
352      a[i] = 0;
353    return FLOATSIZE;
354}*/
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
368  if (x == 0)
369  {
370    exponent = 255;
371    mantisse = 0;
372  }
373  else
374  {
375    //if (x < getDenormConst())
376    //  printf("Denormalisiert!\n");
377    //printf("DenormConst = %e", getDenormConst());
378
379    float sub = 1;
380    while (sub < x)
381    {
382      sub *= 2;
383      exponent++;
384    }
385
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
405    //if (mantisse != 0)
406    //{
407      while (mantisse < expmult)
408      {
409        mantisse *= 2;
410        exponent--;
411      }
412
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    //}
426  }
427
428///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
429
430
431  int hx = mantisse + expmult * exponent;
432  //int result = intToByteArray(hx, a, length);
433  intToByteArray(hx, a, length);
434  if (sgn == -1)
435    a[3] += sgnadd;
436
437
438//  int hx = mantisse + expmult * exponent;
439//  byte* result = intToByteArray(hx);
440//  if (sgn == -1)
441//    result[3] += sgnadd;
442
443  //return result;
444  return FLOATSIZE;
445}
446
447
448/*!
449 * Converts a byte-array into a float value
450 * @param a: The byte-array which is to convert
451 * @param x: The place where the result is to store
452 * @return: The number of read bytes
453 */
454int Converter::byteArrayToFloat(const byte* a, float* x)
455{
456    //handle 0
457  /*for (int i = 0; i<FLOATSIZE; i++)
458  {
459    if (a[i]!=0)
460      break;
461    if ( i==FLOATSIZE-1 )
462    {
463      *x = 0.0f;
464      return FLOATSIZE;
465    }
466}*/
467
468  int hexp = a[2] + a[3] * 256;
469  int exponent = (hexp / 128) % 256;
470
471  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
472  int mantisse = hmant % expmult;
473
474  //handle 0
475  if (mantisse == 0 && exponent == 255)
476  {
477    *x = 0;
478    return FLOATSIZE;
479  }
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  }
490
491  int sgn;
492  if (a[3] >= sgnadd)
493    sgn = -1;
494  else
495    sgn = 1;
496
497///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
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
507  /*
508  float result = mantisse * emult;
509  if (sgn == -1)
510    result = -result;
511
512  return result;
513  */
514
515  *x = mantisse * emult;
516  if (sgn == -1)
517    *x = -  *x;
518
519  return FLOATSIZE;
520}
521
522/*!
523 * Converts a float value into a byte-array
524 * @param x: The float which is to convert
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
528 */
529int Converter::_floatToByteArray(float x, byte* a, int length)
530{
531  if ( length< FLOATSIZE )
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];
540 
541  return FLOATSIZE;
542}
543
544
545/*!
546 * Converts a byte-array into a float value
547 * @param a: The byte-array which is to convert
548 * @param x: The place where the result is to store
549 * @return: The number of read bytes
550 */
551int Converter::_byteArrayToFloat(const byte* a, float* x)
552{
553  *x = *((float*)a);
554
555  return FLOATSIZE;
556}
557
558
559
560
561
562
563
564
565
566
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
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
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
691void Converter::debug()
692{
693  printf("We rulez\n");
694
695  ArrayfloatTest(0.125f);
696  ArrayfloatTest(64.0f);
697  ArrayfloatTest(0.0f);
698  ArrayfloatTest(5.00091e-29f);
699
700  //floatTest(-18.0098f);
701  //floatTest(-24.07e23f);
702  //floatTest(-0.0f);
703  //floatTest(-5.67e-29f);
704 
705 
706  //floatTest(-45.7e-32f);
707  //floatTest(45.7e-33f);
708  //floatTest(-45.7e-34f);
709  //floatTest(45.7e-35f);
710}
Note: See TracBrowser for help on using the repository browser.