Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6736 was 6634, checked in by bensch, 19 years ago

orxonox/trunk: merged the network-branche back to the trunk

merged with command:
svn merge https://svn.orxonox.net/orxonox/branches/network . -r6500:HEAD
minor conflicts in texture and one Makefile resolved to the trunk

also made a small patch to texture, so it Modulates with GL_REPEAT

File size: 11.8 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
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/*!
[6106]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 */
[6341]128int Converter::byteArrayToInt(const byte* a, int* x)
[6106]129{
130  int mult = 1;
131  const int step = 256; // = 2 ^ 8
[6341]132  *x = 0;
[6108]133  for (int i = 0; i < INTSIZE - 1; i++)
[6106]134  {
[6341]135    *x += a[i] * mult;
[6106]136    mult *= step;
137  }
[6341]138
[6108]139  if (a[INTSIZE - 1] >= sgnadd)
[6106]140  {
[6341]141    *x += (a[INTSIZE - 1] - sgnadd) * mult;
142    *x *= -1;
[6106]143  }
144  else
[6341]145    *x += a[INTSIZE - 1] * mult;
146
147  return INTSIZE;
[6106]148}
[6128]149
[6341]150/*!
151 * Converts a float into a string containing its binary representation
152 */
153char* Converter::floatToBinString(float x)
[6128]154{
155  char* result = new char[200];
156  int pos = 0;
[6341]157
158  if (x < 0)
[6128]159  {
[6341]160    result[pos++] = '-';
161    x = -x;
[6128]162  }
[6341]163
164  float sub = 1;
165  while (sub < x)
166    sub *= 2;
167
168  while ((x > 0 || sub >= 1) && pos < 200)
[6128]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;
[6341]179
180    if (sub == 0.5f)
181      result[pos++] = '.';
[6128]182  }
[6341]183
[6128]184  return result;
[6341]185}
[6128]186
[6341]187const int expmult = 8388608; //2^23
188
[6634]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
[6341]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)
[6128]204{
[6634]205  byte* result = new byte[4];
206  floatToByteArray(x, result, 4);
207  return result;
208  /*
[6341]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
[6634]221  if (x == 0)
[6341]222  {
[6634]223    exponent = 255;
224    mantisse = 0;
[6341]225  }
[6634]226  else
227  {
228    //if (x < getDenormConst())
229    //  printf("Denormalisiert!\n");
230    //printf("DenormConst = %e", getDenormConst());
[6341]231
[6634]232    float sub = 1;
233    while (sub < x)
[6128]234    {
[6634]235      sub *= 2;
236      exponent++;
[6128]237    }
[6341]238
[6634]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    }
[6128]267  }
[6341]268
[6634]269  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]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;
[6634]278  */
[6341]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{
[6634]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
[6341]297  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
298  int mantisse = hmant % expmult;
[6634]299  if (mantisse == 0 && exponent == 255)
300    return 0;
301
[6341]302  mantisse += expmult;
[6634]303  exponent -= 128;
[6341]304
305
306  int sgn;
307  if (a[3] >= sgnadd)
308    sgn = -1;
309  else
310    sgn = 1;
311
[6634]312  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]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;
[6634]327  */
[6341]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 */
[6634]335int Converter::_floatToByteArray(float x, byte* a, int length)
[6341]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
[6634]344  /*if ( x == 0 )
[6341]345  {
346    for ( int i = 0; i<FLOATSIZE; i++)
347      a[i] = 0;
348    return FLOATSIZE;
[6634]349}*/
[6341]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
[6634]363  if (x == 0)
[6341]364  {
[6634]365    exponent = 255;
366    mantisse = 0;
[6341]367  }
[6634]368  else
369  {
370    //if (x < getDenormConst())
371    //  printf("Denormalisiert!\n");
372    //printf("DenormConst = %e", getDenormConst());
[6341]373
[6634]374    float sub = 1;
375    while (sub < x)
[6128]376    {
[6634]377      sub *= 2;
378      exponent++;
[6128]379    }
[6341]380
[6634]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    }
[6128]410  }
[6341]411
[6634]412///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]413
414
415  int hx = mantisse + expmult * exponent;
416  int result = intToByteArray(hx, a, length);
417  if (sgn == -1)
418    a[3] += sgnadd;
419
[6634]420
421//  int hx = mantisse + expmult * exponent;
422//  byte* result = intToByteArray(hx);
423//  if (sgn == -1)
424//    result[3] += sgnadd;
425
[6128]426  return result;
427}
[6341]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 */
[6634]435int Converter::_byteArrayToFloat(const byte* a, float* x)
[6341]436{
[6634]437    //handle 0
438  /*for (int i = 0; i<FLOATSIZE; i++)
[6341]439  {
440    if (a[i]!=0)
441      break;
442    if ( i==FLOATSIZE-1 )
443    {
444      *x = 0.0f;
445      return FLOATSIZE;
446    }
[6634]447}*/
[6341]448
[6634]449  int hexp = a[2] + a[3] * 256;
450  int exponent = (hexp / 128) % 256;
[6341]451
452  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
453  int mantisse = hmant % expmult;
[6634]454
455  //handle 0
456  if (mantisse == 0 && exponent == 255)
457  {
458    *x = 0;
459    return FLOATSIZE;
460  }
461
[6341]462  mantisse += expmult;
[6634]463  exponent -= 128;
[6341]464
465
466  int sgn;
467  if (a[3] >= sgnadd)
468    sgn = -1;
469  else
470    sgn = 1;
471
[6634]472///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
[6341]473
474  float emult = 1;
475  if (exponent > 0)
476    for (int i = 0; i < exponent; i++)
477      emult *= 2;
478  else if (exponent < 0)
479    for (int i = 0; i > exponent; i--)
480      emult /= 2;
481
[6634]482  /*
483  float result = mantisse * emult;
484  if (sgn == -1)
485    result = -result;
486
487  return result;
488  */
489
[6341]490  *x = mantisse * emult;
491  if (sgn == -1)
492    *x = -  *x;
493
494  return FLOATSIZE;
495}
496
[6634]497/*!
498 * Converts a float value into a byte-array
499 * @param x: The float which is to convert
500 * @return: A byte-array which accords the given float
501 */
502int Converter::floatToByteArray(float x, byte* a, int length)
503{
504  if ( length<4 )
505  {
506    PRINTF(1)("Byte Array to small\n");
507    return 0;
508  }
509  byte* p = (byte*)&x;
510
511  for (int i = 0; i < 4; i++)
512    a[i] = p[i];
513  return 4;
514}
515
516
517/*!
518 * Converts a byte-array into a float value
519 * @param a: The byte-array which is to convert
520 * @return: A float value which accords the given byte-array
521 */
522int Converter::byteArrayToFloat(const byte* a, float* x)
523{
524  *x = *((float*)a);
525
526  return 4;
527}
528
[6341]529/**
530 * copies a strint to a byte array
531 * @param s: string to copy
532 * @param a: byte array
533 * @param length: string length
534 * @return: the used number of bytes in byte array
535 */
536int Converter::stringToByteArray( const char * s, byte * a, int length, int maxLength )
537{
538  if ( length+INTSIZE > maxLength )
539  {
540    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, length+INTSIZE);
541    return -1;
542  }
543
544  int n = Converter::intToByteArray( length, a, maxLength );
545
546  memcpy( a+INTSIZE, s, length );
547
548  return length + INTSIZE;
549}
550
551/**
552 * reads a string out of a byte array
553 * @param a: byte array
554 * @param s: string
555 * @param maxLength: max bytes to copy
556 * @return: the number of read bytes in byte array
557 */
558int Converter::byteArrayToString( const byte * a, char * s, int maxLength )
559{
560  int length;
561
562  int n = Converter::byteArrayToInt( a, &length );
563
564
565  if ( length+1 > maxLength )
566  {
567    PRINTF(1)("There is not enough space in string (%d) to store %d bytes\n", maxLength, length+1 );
568    strncpy(s,"",maxLength);
569    return -1;
570  }
571
572  memcpy( s, a+n, length );
573  s[length] = '\0';
574
575  return n+length;
576}
577
578/**
579 * reads a string out of a byte array and allocates memory for string
580 * @param a: byte array
581 * @param s: string
582 * @param maxLength: max bytes to copy
583 * @return: the number of read bytes in byte array
584 */
585int Converter::byteArrayToStringM( const byte * a, char*& s )
586{
587  int length;
588
589  int n = Converter::byteArrayToInt( a, &length );
590
591  s = new char[length+1];
592
593  if ( !s )
594  {
595    PRINTF(1)("Could not allocate memory!\n" );
596    return -1;
597  }
598
599  memcpy( s, a+n, length );
600  s[length] = '\0';
601
602  return n+length;
603}
604
[6634]605
606
607
608void Converter::floatTest(float x)
609{
610  //float x = 8.0f;
611  //float x = numeric_limits<float>::infinity();
612
613  printf("To Convert: %e\n", x);
614
615  byte* res = floatToByteArray(x);
616  for (int i = 0; i < 4; i++)
617    printf("%i ", res[i]);
618  printf("\n");
619
620  float y = byteArrayToFloat(res);
621  printf("ReConvert: %e\n", y);
622
623  if (x == y)
624    printf("equal\n");
625  else
626    printf("different\n");
627}
628
629void Converter::debug()
630{
631  printf("We rulez\n");
632
633  //Denormalized?
634  //floatTest(-9.87624e-38f);
635  //floatTest(-9.87624e-37f);
636  //floatTest(-9.87624e-36f);
637  //floatTest(-9.87624e-35f);
638
639  /*
640  floatTest(14.7f);
641  floatTest(12.07e15f);
642  floatTest(0.0f);
643  floatTest(5.67e-15f);
644  */
645
646  //floatTest(-18.0098f);
647  //floatTest(-24.07e23f);
648  //floatTest(-0.0f);
649  //floatTest(-5.67e-29f);
650  floatTest(-45.7e-32f);
651  floatTest(45.7e-33f);
652  floatTest(-45.7e-34f);
653  floatTest(45.7e-35f);
654}
Note: See TracBrowser for help on using the repository browser.