A piece of code related to DSP

N

narke

Hi,

I have a big code, and I cannot get understand some parts of it. Below
is a piece of them:

void determind_corr_value(void)
{
int8_t Leading0;
uint32_t CorrValue;

...

if( CorrValue>0)
{
// Detect bit number of MSB of CorrValue (Leading 0's are
counted)
Leading0 = 1;

while(!(*((int16_t*) &CorrValue + 1) < 0)) // MS_Bit = 0
{
CorrValue <<= 1;
Leading0++;
}

Leading0 -= 8;

// increase the resolution for compensation steps to 0.5Bit by
checking the 2nd bit
//lint -save -e701
Leading0 <<= 1;
if(*((int16_t*) &CorrValue + 1) & 0x4000)
{
Leading0--;
}

// Calculate now the correction value
if( Current < CalibrationData.I_Limit_Corr) {
// low range
Leading0-= (int8_t)Data.Leading0_Corr_Low;

CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_Low * Leading0)));
} else {
// High range
Leading0-= (int8_t)Data.Leading0_Corr_High;

CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_High * Leading0)));
}

} else
CorrValue = 32768;

...
}


I guess it was doing some kind of DSP, but not sure what was exactly
going on. Especially, I hope some one have a guess and give me some
hints for my below questions so far:

1. Why Leading0 was assigned as 1 at begin of the process.
2. Why 8 was substracted from the Leading0
3. What means 0.5bit and checking for 2nd bit?
4. Why 32768?

I hope the code indeed implemented some algorithm that is familiar to
some of you.


Regards,
woody
 
J

Jason

Hi,

I have a big code, and I cannot get understand some parts of it. Below
is a piece of them:

void determind_corr_value(void)
{
   int8_t Leading0;
   uint32_t CorrValue;

   ...

   if( CorrValue>0)
   {
      // Detect bit number of MSB of CorrValue (Leading 0's are
counted)
      Leading0 = 1;

      while(!(*((int16_t*) &CorrValue + 1) < 0))   // MS_Bit = 0
      {
         CorrValue <<= 1;
         Leading0++;
      }

      Leading0 -= 8;

      // increase the resolution for compensation steps to 0.5Bit by
checking the 2nd bit
      //lint -save -e701
      Leading0 <<= 1;
      if(*((int16_t*) &CorrValue + 1) & 0x4000)
      {
         Leading0--;
      }

      // Calculate now the correction value
      if( Current < CalibrationData.I_Limit_Corr) {
         // low range
         Leading0-= (int8_t)Data.Leading0_Corr_Low;

         CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_Low * Leading0)));
      } else {
         // High range
         Leading0-= (int8_t)Data.Leading0_Corr_High;

         CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_High * Leading0)));
      }

   } else
      CorrValue = 32768;

   ...

}

I guess it was doing some kind of DSP, but not sure what was exactly
going on.  Especially, I hope some one have a guess and give me some
hints for my below questions so far:

1. Why Leading0 was assigned as 1 at begin of the process.
2. Why 8 was substracted from the Leading0
3. What means 0.5bit and checking for 2nd bit?
4. Why 32768?

I hope the code indeed implemented some algorithm that is familiar to
some of you.

Regards,
woody

You may not ever get any meaningful comments on this abomination of a
function, but without any kind of context, it's even more difficult to
figure out what is going on. Do you have any idea what it's used for?

Jason
 
W

William Hughes

Hi,

I have a big code, and I cannot get understand some parts of it. Below
is a piece of them:

void determind_corr_value(void)
{
   int8_t Leading0;
   uint32_t CorrValue;

   ...

   if( CorrValue>0)
   {
      // Detect bit number of MSB of CorrValue (Leading 0's are
counted)
      Leading0 = 1;

      while(!(*((int16_t*) &CorrValue + 1) < 0))   // MS_Bit = 0
      {
         CorrValue <<= 1;
         Leading0++;
      }

      Leading0 -= 8;

      // increase the resolution for compensation steps to 0.5Bit by
checking the 2nd bit
      //lint -save -e701
      Leading0 <<= 1;
      if(*((int16_t*) &CorrValue + 1) & 0x4000)
      {
         Leading0--;
      }

      // Calculate now the correction value
      if( Current < CalibrationData.I_Limit_Corr) {
         // low range
         Leading0-= (int8_t)Data.Leading0_Corr_Low;

         CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_Low * Leading0)));
      } else {
         // High range
         Leading0-= (int8_t)Data.Leading0_Corr_High;

         CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_High * Leading0)));
      }

   } else
      CorrValue = 32768;

   ...

}

I guess it was doing some kind of DSP, but not sure what was exactly
going on.

This is horrible. Basically the idea is to take a 16 bit
CorrValue (stored in the second half of a 32 bit integer)
and use it to choose one of 32 correction values.

There is also a sort of a truncated log transform. The
coder had decided to use bit manipulation, probably as
a dubious offering to the great god efficiency.
It also has the feel of 16 bit code shoehorned into
a 32 bit system.


If there is any way you can get away from this
code do so. Find out what needs to be done and code
from scratch.

 Especially, I hope some one have a guess and give me some
hints for my below questions so far:

1. Why Leading0 was assigned as 1 at begin of the process.

Leading0 starts out as the MSB. The MSB starts at 1.
2. Why 8 was substracted from the Leading0

Leading 0 has to become a signed quantity. If
the MSB is small, then the correction value will
be less than 32768 and Leading0 has to be negative.
Note the correction value will be changed
by some multiple of the (shifted) MSB. This
is a log transform.

3. What means 0.5bit and checking for 2nd bit?

Rather that using one bit (16 possible positions)
the code uses two bits (32 possible positions)
4. Why 32768?

This is 2^15, half of an unsigned 16 bit quantity. The correction
values are meant to fill a 16 bit unsigned integer.

- William Hughes
 
S

Steve Pope

io_x said:
"Jason" <[email protected]> ha scritto nel messaggio
the problem i have here: !*a<0 means !(*a<0), or it means ((!*a)<0)?
i think it is the second one

If means ((!*a) < 0), since ! and * have precedence over <; which means
specifically ((!(*a)) < 0). (Prefix operators of the same precedence,
such as ! and *, associate right to left.)


Steve
 
B

Ben Bacarisse

io_x said:
"Jason" <[email protected]> ha scritto nel messaggio
On May 13, 10:00 am, narke <[email protected]> wrote:

the problem i have here: !*a<0 means !(*a<0), or it means ((!*a)<0)?
i think it is the second one

!*a<0 means (!*a) < 0 but that is not what was written. The ! is
outside a fully parenthesised relational expression:

!(E < 0) or E >= 0

By the way, I agree entirely with your re-write (in a subsequent post).
Using array notation is much clearer:

int16_t *half_word = (void *)&CorrValue;
while (half_word[1] >= 0) ...

however this still confuses significance with address order (i.e. it
assumes endianness).

<snip>
 
S

Steve Pope

Ben Bacarisse said:
!*a<0 means (!*a) < 0 but that is not what was written. The ! is
outside a fully parenthesised relational expression:

!(E < 0) or E >= 0

By the way, I agree entirely with your re-write (in a subsequent post).
Using array notation is much clearer:

int16_t *half_word = (void *)&CorrValue;
while (half_word[1] >= 0) ...

however this still confuses significance with address order (i.e. it
assumes endianness).

Tangentially, there are these nice things called log functions
in the math libraries that can be used for leading zero counts.

It is (usually) no longer necessary to worry about library functions
being too slow and hand-coding this stuff...

Steve
 
N

narke

You may not ever get any meaningful comments on this abomination of a
function, but without any kind of context, it's even more difficult to
figure out what is going on. Do you have any idea what it's used for?

The program is running on an high end electrical meter. The meter has
an embedded DSP chip than can measure current/voltage/energy that
inputed to the meter. every one seconds (actually even small), the
program in the meter talks with the chip, retrieve back its data and
do some post process. In this piece of code, the program is do a
calculation that has something to do with the correction value or
compensation value that will be laterly applied to the inputed current
quantities.
 
N

narke

This is horrible. Basically the idea is to take a 16 bit
CorrValue (stored in the second half of a 32 bit integer)
and use it to choose one of 32 correction values.

Interesting! Why do you think the second part of the CorrValue is an
index and where are the 32 correction values?

There is also a sort of a truncated log transform. The
coder had decided to use bit manipulation, probably as
a dubious offering to the great god efficiency.
It also has the feel of 16 bit code shoehorned into
a 32 bit system.

God, you are righ! the microprocess had upgraded from 16bit to 32bit
long time ago, so the original 16bit code had been ported to 32bit.

I want to know more about what you said, log transform. I mean, I do
know what is logarithm transform but I can not identify where is the
logarithm operation in the code. Can you help?
If there is any way you can get away from this
code do so. Find out what needs to be done and code
from scratch.



Leading0 starts out as the MSB. The MSB starts at 1.

I don't get it. By 'MSB starts at 1', did you mean the position of
the MSB is the second couting from left? So, how will you call the
first bit counting from left?
Leading 0 has to become a signed quantity. If
the MSB is small, then the correction value will
be less than 32768 and Leading0 has to be negative.
Note the correction value will be changed
by some multiple of the (shifted) MSB. This
is a log transform.

Fully don't understand. Could you explain in more detail?
Rather that using one bit (16 possible positions)
the code uses two bits (32 possible positions)

why:
one bit --> 16
two bit --> 32
This is 2^15, half of an unsigned 16 bit quantity. The correction
values are meant to fill a 16 bit unsigned integer.

Did you mean, if that is 2^15, then it can be ensure the correction
value will fill into a 16 bit unsigned? Is there a reasoning?
 
N

narke

i don't see why not write it in this way
%define MS_Bit 0x00008000

while((CorrValue & MS_Bit)==0)
{CorrValue <<= 1;
Leading0++;
if(CorrValue==0) return error2349;
}

i don't know if it is right...

It's the same but more clear. I also has a same feeling with you.
 
W

William Hughes

Interesting!  Why do you think the second part of the CorrValue is an
index and where are the 32 correction values?




God, you are righ!  the microprocess had upgraded from 16bit to 32bit
long time ago, so the original 16bit code had been ported to 32bit.

I want to know more about what you said, log transform.  I mean, I do
know what is logarithm transform but I can not identify where is the
logarithm operation in the code. Can you help?


The transform is (more or less)

correction_value =
middle_value + 2*(MSB-8)*step_value

MSB can only take on one of 32 values. Note that
MSB= C log(Corr_Value) for some constant C.
This is a log transform.

Things are not quite a simple as the above
(for example step_value has one of two values)


Use this code *for anything* (including finding
out what needs to be done) only under duress
(e.g. the code is all there is).

Find out who originally wrote this code.
Hunt him down and kill him.

Find out who ported this code. Hunt him/her
down and cause serious pain.

Find out what transform is needed, then code
it directly.

I don't get it.  By 'MSB starts at 1', did you mean the position of
the MSB is the second couting from left? So, how will you call the
first bit counting from left?

No the first position from the left is called 1, not 0.
The MSB numbering makes little sense anyway. Why expect
it to use 0 indexing.
Fully don't understand.  Could you explain in more detail?





why:
one bit --> 16
two bit --> 32

The MSB bit can be in 16 places. For each the next bit
can be 0 or 1.

- William Hughes
 
I

Ian Collins

because i not like "const"; yes it should be better if i write
%define MS_Bit 0x00008000
functionsThatUseAboveMacro()
....
functionsThatUseAboveMacro1()
....
functionsThatUseAboveMacro2()
....
functionsThatUseAboveMacro3()
%undef MS_Bit

Why? MS_Bit is a const uint32_t, so why not declare it as one?

#define really should be reserved for compile time constants when an
enum value can't be used.
 
N

narke

["Followup-To:" header set to comp.lang.c.]
The transform is (more or less)

correction_value =
middle_value + 2*(MSB-8)*step_value

Many thanks, I now begin to understand the transform. MSB here actually defined
as: 32 - int(log2(correction_value)). Am I right? And, inspired from the name
'step_value', I think it would be better to call it 'scale_value', how do you
think it?

Another question is 'middle_value' (thanks for the name). As you seen,
middle_value here is 32768, it looks like middle value of 2^16. But, why
choice so although correct_value is a unsigned 32bit integer?

That finally question about the equation is that: what likely is the true
purpose of the transform? Is there a mathematic model behind it? Do you have any
guess if I tell you the 'correct_value' is initially a RMS current value?
MSB can only take on one of 32 values. Note that
MSB= C log(Corr_Value) for some constant C.
This is a log transform.

Things are not quite a simple as the above
(for example step_value has one of two values)


Use this code *for anything* (including finding
out what needs to be done) only under duress
(e.g. the code is all there is).

Find out who originally wrote this code.
Hunt him down and kill him.

Find out who ported this code. Hunt him/her
down and cause serious pain.

Find out what transform is needed, then code
it directly.



No the first position from the left is called 1, not 0.
The MSB numbering makes little sense anyway. Why expect
it to use 0 indexing.

The MSB bit can be in 16 places. For each the next bit
can be 0 or 1.

Are you sure? It should be: the MSB bit can be in *32* places, and for each the
next bit can be 0 or 1.
 
J

Jerry Avins

On 5/15/2010 10:49 PM, narke wrote:

...
Another question is 'middle_value' (thanks for the name). As you seen,
middle_value here is 32768, it looks like middle value of 2^16. But, why
choice so although correct_value is a unsigned 32bit integer?

On a log scale, 2^16 is half way to 2^32.
That finally question about the equation is that: what likely is the true
purpose of the transform? Is there a mathematic model behind it? Do you have any
guess if I tell you the 'correct_value' is initially a RMS current value?

The measurement system may be non-linear, probably due to iron
saturation in the current transformer. Determining the range allows a
correction to be selected from a look-up table.

...

Jerry
 
W

William Hughes

["Followup-To:" header set to comp.lang.c.]
The transform is (more or less)
correction_value =
    middle_value + 2*(MSB-8)*step_value

Many thanks, I now begin to understand the transform. MSB here actually defined
as:  32 - int(log2(correction_value)).  Am I right?  And, inspired from the name
'step_value', I think it would be better to call it 'scale_value',  how do you
think it?

Another question is 'middle_value' (thanks for the name).  As you seen,
middle_value here is 32768, it looks like middle value of 2^16.  But, why
choice so although correct_value is a unsigned 32bit integer?

That finally question about the equation is that: what likely is the true
purpose of the transform? Is there a mathematic model behind it? Do you have any
guess if I tell you the 'correct_value' is initially a RMS current value?




MSB can only take on one of 32 values. Note that
MSB= C log(Corr_Value) for some constant C.
This is a log transform.
Things are not quite a simple as the above
(for example step_value has one of two values)
Use this code *for anything*  (including finding
out what needs to be done) only under duress
(e.g. the code is all there is).
Find out who originally wrote this code.
Hunt him down and kill him.
Find out who ported this code.  Hunt him/her
down and cause serious pain.
Find out what transform is needed, then code
it directly.
No the first position from the left is called 1, not 0.
The MSB numbering makes little sense anyway.  Why expect
it to use 0 indexing.
The MSB bit can be in 16 places.  For each the next bit
can be 0 or 1.

Are you sure?  It should be: the MSB bit can be in *32* places, and for each the
next bit can be 0 or 1.


                        - William Hughes

Note that although stored in a 32 bit int, the correction
value is actually an unsigned 16 bit value.
MSB can have values of 1 to 16. In fact MSB seems to be
17- int(log2(CorrValue)) (correction_value cannot
be 0 or this function blows up)

The "output" is also really 16 bits, and 32768 is half way.
(Note there *is* no output, The function is type void
and is passed nothing)

A log transform is quite common. I don't have any good
guess as to exactly why one is used in this application.
(Maybe simply to allow very small currents to give an
appreciable reading?)
- William Hughes
 
N

narke

["Followup-To:" header set to comp.lang.c.]
I have a big code, and I cannot get understand some parts of it. Below
is a piece of them:
void determined_corr_value(void)
{
? ?int8_t Leading0;
? ?uint32_t CorrValue;
? ?if( CorrValue>0)
? ?{
? ? ? // Detect bit number of MSB of CorrValue (Leading 0's are
counted)
? ? ? Leading0 = 1;
? ? ? while(!(*((int16_t*) &CorrValue + 1) < 0)) ? // MS_Bit = 0
? ? ? {
? ? ? ? ?CorrValue <<= 1;
? ? ? ? ?Leading0++;
? ? ? }
? ? ? Leading0 -= 8;
? ? ? // increase the resolution for compensation steps to 0.5Bit by
checking the 2nd bit
? ? ? //lint -save -e701
? ? ? Leading0 <<= 1;
? ? ? if(*((int16_t*) &CorrValue + 1) & 0x4000)
? ? ? {
? ? ? ? ?Leading0--;
? ? ? }
? ? ? // Calculate now the correction value
? ? ? if( Current < CalibrationData.I_Limit_Corr) {
? ? ? ? ?// low range
? ? ? ? ?Leading0-= (int8_t)Data.Leading0_Corr_Low;
? ? ? ? ?CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_Low * Leading0)));
? ? ? } else {
? ? ? ? ?// High range
? ? ? ? ?Leading0-= (int8_t)Data.Leading0_Corr_High;
? ? ? ? ?CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_High * Leading0)));
? ? ? }
? ?} else
? ? ? CorrValue = 32768;
? ?...

I guess it was doing some kind of DSP, but not sure what was exactly
going on.
This is horrible. Basically the idea is to take a 16 bit
CorrValue (stored in the second half of a 32 bit integer)
and use it to choose one of 32 correction values.
Interesting! Why do you think the second part of the CorrValue is an
index and where are the 32 correction values?
There is also a sort of a truncated log transform. The
coder had decided to use bit manipulation, probably as
a dubious offering to the great god efficiency.
It also has the feel of 16 bit code shoehorned into
a 32 bit system.
God, you are right! The microprocessor had upgraded from 16bit to 32bit
long time ago, so the original 16bit code had been ported to 32bit.
I want to know more about what you said, log transform. I mean, I do
know what is logarithm transform but I can not identify where is the
logarithm operation in the code. Can you help?
The transform is (more or less)
correction_value =
middle_value + 2*(MSB-8)*step_value

Many thanks, I now begin to understand the transform. MSB here actually
defined as:
32 - int(log2(correction_value)). Am I right? And, inspired from the
name
'step_value', I think it would be better to call it 'scale_value', How do you
think it?

Another question is 'middle_value' (thanks for the name). As you seen,
middle_value here is 32768, it looks like middle value of 2^16. But, why
choice so although correct_value is a unsigned 32bit integer?

That finally question about the equation is that: what likely is the true
purpose of the transform? Is there a mathematic model behind it? Do you
have any
guess if I tell you the 'correct_value' is initially a RMS current value?




MSB can only take on one of 32 values. Note that
MSB= C log(Corr_Value) for some constant C.
This is a log transform.
Things are not quite a simple as the above
(for example step_value has one of two values)
Use this code *for anything* including finding
out what needs to be done) only under duress
(e.g. the code is all there is).
Find out who originally wrote this code.
Hunt him down and kill him.
Find out who ported this code. Hunt him/her
down and cause serious pain.
Find out what transform is needed, then code
it directly.
If there is any way you can get away from this
code do so. Find out what needs to be done and code
from scratch.
?Especially, I hope some one have a guess and give me some
hints for my below questions so far:
1. Why Leading0 was assigned as 1 at begin of the process.
Leading0 starts out as the MSB. The MSB starts at 1.
I don't get it. Why 'MSB starts at 1', did you mean the position of
the MSB is the second counting from left? So, how will you call the
first bit counting from left?
No the first position from the left is called 1, not 0.
The MSB numbering makes little sense anyway. Why expect
it to use 0 indexing.
2. Why 8 was subtracted from the Leading0
Leading 0 has to become a signed quantity. If
the MSB is small, then the correction value will
be less than 32768 And Leading0 has to be negative.
Note the correction value will be changed
by some multiple of the (shifted) MSB. This
is a log transform.
Fully don't understand. Would you explain in more detail?
3. What means 0.5bit and checking for 2nd bit?
Rather that using one bit (16 possible positions)
the code uses two bits (32 possible positions)
why:
one bit --> 16
two bit --> 32
The MSB bit can be in 16 places. For each the next bit
can be 0 or 1.

Are you sure? It should be: the MSB bit can be in *32* places, and for
each the
next bit can be 0 or 1.


- William Hughes

Note that although stored in a 32 bit int, the correction
value is actually an unsigned 16 bit value.
MSB can have values of 1 to 16. In fact MSB seems to be
17- int(log2(CorrValue)) (correction_value cannot
be 0 or this function blows up)

Are you sure William? From the code:

while(!(*((int16_t*) &CorrValue + 1) < 0)) ? // MS_Bit = 0
{
CorrValue <<= 1;
Leading0++;
}

I can see, the loop can execute from 0 times to 31 times. so the MSB ranges from
1 (when CorrValue = 0x80000000) to 32 (when CorrValue = 0x00000001).

And, I don't see a clue that shows CorrValue is actually unsigned 16 bit value.
Can you explain a little more? Thanks.
The "output" is also really 16 bits, and 32768 is half way.

Yes, if the output is 16 bit, 32768 is reasonable according to your explains
before. The problem is that I don't see the output is 16 bit.
(Note there *is* no output, The function is type void
and is passed nothing)

Yes, the transform function is implicitly embedded in the C function.
A log transform is quite common. I don't have any good
guess as to exactly why one is used in this application.
(Maybe simply to allow very small currents to give an
appreciable reading?)
- William Hughes

Okay, let's get clear the transform itself first. And, if I want to study some
applications about logarithm transform, do you have a suggestion for a internet
resource? Thanks.


I am looking forward for you answer and I will see you've already help me so
much so far.

-
narke
 
N

narke

On 5/15/2010 10:49 PM, narke wrote:

...


On a log scale, 2^16 is half way to 2^32.

Sounds like a point ... but 32768 is not 2^16 :( On the other
hand, 32768 was applied just before the output was delivered,
where there is no a log scale.
The measurement system may be non-linear, probably due to iron
saturation in the current transformer. Determining the range allows a
correction to be selected from a look-up table.

I will think about it, thanks for the hint!
 
W

William Hughes

["Followup-To:" header set to comp.lang.c.]
On Thu, 13 May 2010 10:07:00 -0700 (PDT), William Hughes
Hi,
I have a big code, and I cannot get understand some parts of it. Below
is a piece of them:
void determined_corr_value(void)
{
? ?int8_t Leading0;
? ?uint32_t CorrValue;
? ?...
? ?if( CorrValue>0)
? ?{
? ? ? // Detect bit number of MSB of CorrValue (Leading 0's are
counted)
? ? ? Leading0 = 1;
? ? ? while(!(*((int16_t*) &CorrValue + 1) < 0)) ? // MS_Bit = 0
? ? ? {
? ? ? ? ?CorrValue <<= 1;
? ? ? ? ?Leading0++;
? ? ? }
? ? ? Leading0 -= 8;
? ? ? // increase the resolution for compensation steps to 0.5Bit by
checking the 2nd bit
? ? ? //lint -save -e701
? ? ? Leading0 <<= 1;
? ? ? if(*((int16_t*) &CorrValue + 1) & 0x4000)
? ? ? {
? ? ? ? ?Leading0--;
? ? ? }
? ? ? // Calculate now the correction value
? ? ? if( Current < CalibrationData.I_Limit_Corr) {
? ? ? ? ?// low range
? ? ? ? ?Leading0-= (int8_t)Data.Leading0_Corr_Low;
? ? ? ? ?CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_Low * Leading0)));
? ? ? } else {
? ? ? ? ?// High range
? ? ? ? ?Leading0-= (int8_t)Data.Leading0_Corr_High;
? ? ? ? ?CorrValue = (unsigned)(long)(32768L + ((int16_t)
(CalibrationData.Correction_High * Leading0)));
? ? ? }
? ?} else
? ? ? CorrValue = 32768;
? ?...
}
I guess it was doing some kind of DSP, but not sure what was exactly
going on.
This is horrible. Basically the idea is to take a 16 bit
CorrValue (stored in the second half of a 32 bit integer)
and use it to choose one of 32 correction values.
Interesting! Why do you think the second part of the CorrValue is an
index and where are the 32 correction values?
There is also a sort of a truncated log transform. The
coder had decided to use bit manipulation, probably as
a dubious offering to the great god efficiency.
It also has the feel of 16 bit code shoehorned into
a 32 bit system.
God, you are right! The microprocessor had upgraded from 16bit to 32bit
long time ago, so the original 16bit code had been ported to 32bit.
I want to know more about what you said, log transform. I mean, I do
know what is logarithm transform but I can not identify where is the
logarithm operation in the code. Can you help?
The transform is (more or less)
correction_value =
   middle_value + 2*(MSB-8)*step_value
Many thanks, I now begin to understand the transform. MSB here actually
defined as:
 32 - int(log2(correction_value)). Am I right? And, inspired from the
name
'step_value', I think it would be better to call it 'scale_value', How do you
think it?
Another question is 'middle_value' (thanks for the name). As you seen,
middle_value here is 32768, it looks like middle value of 2^16. But, why
choice so although correct_value is a unsigned 32bit integer?
That finally question about the equation is that: what likely is the true
purpose of the transform? Is there a mathematic model behind it? Do you
have any
guess if I tell you the 'correct_value' is initially a RMS current value?
MSB can only take on one of 32 values. Note that
MSB= C log(Corr_Value) for some constant C.
This is a log transform.
Things are not quite a simple as the above
(for example step_value has one of two values)
Use this code *for anything* including finding
out what needs to be done) only under duress
(e.g. the code is all there is).
Find out who originally wrote this code.
Hunt him down and kill him.
Find out who ported this code. Hunt him/her
down and cause serious pain.
Find out what transform is needed, then code
it directly.
If there is any way you can get away from this
code do so. Find out what needs to be done and code
from scratch.
?Especially, I hope some one have a guess and give me some
hints for my below questions so far:
1. Why Leading0 was assigned as 1 at begin of the process.
Leading0 starts out as the MSB. The MSB starts at 1.
I don't get it. Why 'MSB starts at 1', did you mean the position of
the MSB is the second counting from left? So, how will you call the
first bit counting from left?
No the first position from the left is called 1, not 0.
The MSB numbering makes little sense anyway. Why expect
it to use 0 indexing.
2. Why 8 was subtracted from the Leading0
Leading 0 has to become a signed quantity. If
the MSB is small, then the correction value will
be less than 32768 And Leading0 has to be negative.
Note the correction value will be changed
by some multiple of the (shifted) MSB. This
is a log transform.
Fully don't understand. Would you explain in more detail?
3. What means 0.5bit and checking for 2nd bit?
Rather that using one bit (16 possible positions)
the code uses two bits (32 possible positions)
why:
one bit --> 16
two bit --> 32
The MSB bit can be in 16 places. For each the next bit
can be 0 or 1.
Are you sure? It should be: the MSB bit can be in *32* places, and for
each the
next bit can be 0 or 1.
- William Hughes
Note that although stored in a 32 bit int, the correction
value is actually an unsigned 16 bit value.
MSB can have values of 1 to 16.  In fact MSB seems to be
17- int(log2(CorrValue))  (correction_value cannot
be 0 or this function blows up)

Are you sure William?  From the code:

while(!(*((int16_t*) &CorrValue + 1) < 0)) ? // MS_Bit = 0
{
    CorrValue <<= 1;
    Leading0++;

}

I can see, the loop can execute from 0 times to 31 times. so the MSB ranges from
1 (when CorrValue = 0x80000000) to 32 (when CorrValue = 0x00000001).


Because of the cast to (int16_t*) you are dealing with
a 16 bit signed quantity, You keep shifting until this
quantity is negative, i.e. when the leading 1 bit is shifted
to the sign bit position. (This is platform dependent and obfuscated.)
And, I don't see a clue that shows CorrValue is actually unsigned 16 bit value.
Can you explain a little more? Thanks.




Yes, if the output is 16 bit, 32768 is reasonable according to your explains
before.  The problem is that I don't see the output is 16  bit.

There is no output. A value is stored in the 32 bit type
local CorrValue (how this gets outside the function I have
no idea.

Yes, the transform function is implicitly embedded in the C function.




Okay, let's get clear the transform itself first.

Good idea, but use the code only if you have no
other option.
 And, if I want to study some
applications about logarithm transform, do you have a suggestion for a internet
resource?  Thanks.

Unfortunately no.
 
N

narke

Because of the cast to (int16_t*) you are dealing with
a 16 bit signed quantity, You keep shifting until this
quantity is negative, i.e. when the leading 1 bit is shifted
to the sign bit position. (This is platform dependent and obfuscated.)

I would not say dealing with 16 bit signed quality, rather treat the
high part of a 32 bit value as a 16 bit signed value. Anyway, the
operation is actually check the highest bit of the 32 bit value, if that
is not one, shift until it is, and increase the counter each time when
the value shifted.

I tested this piece of loop code, and I say, the result proves that I am
right, the MSB value ranges from 1 to 32. What is the byte ordering in
your system? On my testing system as well as the target platform, it is
little endian.

There is no output. A value is stored in the 32 bit type
local CorrValue (how this gets outside the function I have
no idea.

Hum ... I now understand your concern. Actually it is my fault, because
it's almost impossible to show the whole code in Usenet, I modified the
code to declear some global variable as local variable (with same data
type). CorrValue is, in the original program, global value :)
Good idea, but use the code only if you have no
other option.

Yes, for the moment, I don't have a document for the code. So I have to
get know from the code that what is the hell transform. And, I belive,
the result can also help me understand the problem domain itself.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top