I believe there is a function which returns the max value for a double, however, I do not need this. I'm converting the following function:

``````public void StaticCompress(short[] samples, float param)
{
for (int i = 0; i < samples.Length; i++)
{
int sign = (samples[i] < 0) ? -1 : 1;
float norm = ABS(samples[i] / 32768); // NOT short.MaxValue
norm = 1.0 - POW(1.0 - norm, param);
samples[i] = 32768 * norm * sign;
}
}
``````

But instead of using `shorts` I pass in a `double` array. Anyone have any suggestions?

I think it is 1.79769e+308.

You can access it via numeric_limits::max

i.e. -

``````#include <limits>
``````

If you then output a statement for this limit for type double, it should give the number I gave up top.

But in the line:

``````float norm = ABS(samples[i] / 32768); // NOT short.MaxValue
``````

It tells me not to use `short.MaxValue` so I assumed that `numeric_limits::max` will do the same as this?

What is telling you not to use short.MaxValue? The compiler?

Perhaps you could use a macro instead. This is what is in <cfloat> itself:

``````#define DBL_MAX 1.7976931348623158e+308
``````

Include <cfloat> in your program, use DBL_MAX in that line, and see what happens.

The problem with using the maximum value of a double is that you will most certainly lose all meaningful value in your samples array. For example, if you do `samples[i] / std::numeric_limits<double>::max()`, then it won't really matter much what the value of `samples[i]` is, unless it is extremely close to the maximum value. What you'll get is just a number extremely close to zero, within the number of significant digits. So, I don't think that such a strategy would make any sense. You need to rely on a meaningful upper-bound to your sample values.

When I see this code `ABS(samples[i] / 32768);`, to me, this looks like just a normal ADC (Analog-Digital Conversion) sample conversion to a floating point value normalized to the 0-1 range. This is because ADC units take an analog signal and convert it to a digital signal of a certain number of bits `N`, and thus, to an integer value within a range `[0, 2^N]`. To map that integer value back to the range of the analog signal (0 to 5 Volts, or just 0 to 1 in normalized units), you have to perform a very simple conversion, like `samples[i] / 32768`.

So, you have to see that function as doing this:

``````public void StaticCompress(short[] samples, float param)
{
for(int i = 0; i < samples.Length; i++)
{
int sign = get_sign_of(samples[i]);
float norm = normalize_abs_value( samples[i] );
norm = 1.0 - POW(1.0 - norm, param);
samples[i] = denormalize_value( norm * sign );
}
}
``````

where in the case of a full-range 16bit ADC sample, the normalize / denormalize process is just a division or multiplication by `2^15`.

But if you have double values coming in, then they have their own range already, which is certainly not `[- std::numeric_limits<double>::max(), std::numeric_limits<double>::max()]`. You need to know the meaningful range for those values, period.

It tells me not to use `short.MaxValue`

The reason it tells you that the 32768 is not the `short.MaxValue` is because the person who wrote that code was working on the same principle I just explained. The value `32768` is not the maximum value of a short (well, it is, but by coincidence only), it is the maximum of the meaningful range of the sample values. And you need to apply the same principle if you are going to use something else, like doubles.

Another example, it is not uncommon to have weird ADC bit numbers. For example, you could have a 6-bit ADC unit, meaning that you can store the samples in a byte (8 bits), but the meaningful range is only 6 bits (the other two are always zero). So, in that case, the conversion factor would be either 32 or 64, depending on whether the value is signed or unsigned.

commented: Thanks for the input Mike. Your posts are always thorough, going above and beyond simply answering the question +5

I think it is 1.79769e+308.

It's implementation defined.

It tells me not to use `short.MaxValue` so I assumed that `numeric_limits::max` will do the same as this?

The two are roughly synonymous. I suspect the comment is saying not to use `short.MaxValue` because `short.MaxValue` gives you 32767 rather than 32768, which breaks the algorithm.

So in the `normalize_abs_value` function, I would take the value of `samples[i]` and then multiply by 2 to the power of 15?

multiply by 2 to the power of 15?

`2^15 == 32768`, I thought that was obvious.

All I did in that code was replace a line of code by an abstract function call, it was just to make you think about it at an abstract level, instead of just focusing on the details. You look at the initial piece of code and see a "division by the maximum value", and then, you wonder how to do the same when the type is `double` instead of `short`. What I want you to see in that piece of code is a "normalization to a range of `[0,1]`", and then, ask yourself what would be a meaningful normalization for your problem domain. For the author of the code, in his problem domain, the meaningful normalization was a conversion between the range `[-32768, 32768]` to `[-1.0, 1.0]`. What is yours?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.