Ok, that is very surprising, so I did more checking. It looks like your
original results were optimized? I tried without any optimization flags,
which leads to good results. But when I optimize, I see the same as you.

What's going on is that when not optimizing, the emitted code uses
Math_pow. But when optimizing, LLVM emits an exp2f libc call. We implement
generic pow using Math.pow, but exp2f using the musl libc. And it turns out
that in musl exp2f, not having proper float32 precision leads to inaccuracy
that causes the bad results.

In other words, we are running different code for pow when optimizing and
when not. This sort of makes sense, as I do see the musl methods as being
faster, but perhaps we should reconsider that? Regardless, when building
with PRECISE_F32=1 (not 0 or 2) there is a guarantee of proper float32
precision, and the results are as they should be.

In this case here, which is best for your app depends on whether
performance or precision is most important. If you get decent speed with
your option 2, I would go with that (use your normal C code, build with
PRECISE_F32 support, but I would use 1 and not 2 in this case, as some
browsers will not have fround, and will get the bad results with option 2).

- Alon



On Wed, Jan 28, 2015 at 11:19 PM, Stéphane Letz <[email protected]> wrote:

> Problem occurring on both Chrome 40.0.2214.93 (64-bit) and Firefox 35.0.1
> on OSX 10.8.5.
>
> I wasn't aware of this PRECISE_F32 flag, thanks. But I'm a but confused
> here, the documentation says :
>
> ar PRECISE_F32 = 0; // 0: Use JS numbers for floating-point values. These
> are 64-bit and do not model C++
>
>                      //    floats exactly, which are 32-bit.
>
> Now if I use the following JS code instead of C in the first place, it
> works:
>
> midiToFreq = function (note)
>
> {
>
>     return 440.0 * Math.pow(2.0, (note - 69.0) / 12.0);
> }
>
> Then using -s PRECISE_F32=1 or -s PRECISE_F32=2 works, and I read
> that PRECISE_F32=2 is preferable. So now what is the best option:
>
> 1) just use the "double" midiToFreq version in the original C code and
> emcripten
>
> 2) or use the "float" version in the C original C code, emcripten
> and -s PRECISE_F32=2
>
> 3) to just avoid the C midiToFreq and use the pure JS midiToFreq version
> instead?
>
> Thanks.
>
> Stéphane
>
> Le jeudi 29 janvier 2015 00:30:32 UTC+1, Alon Zakai a écrit :
>>
>> Which platform and which JS engine is that?
>>
>> There are several possible issues here. The JS engine might be using the
>> system libc pow, but it might have it's own implementation (e.g. sin and
>> cos have been implemented in browsers), and different libcs and so forth
>> can be more or less precise. Also, since there are floats here, building
>> with -s PRECISE_F32=1 can make the results more like native. With that I
>> get almost identical results, but still some tiny rounding errors. But even
>> without it, the errors are much smaller than yours.
>>
>> - Alon
>>
>>
>>
>> On Wed, Jan 28, 2015 at 1:43 PM, Stéphane Letz <[email protected]> wrote:
>>
>>> The following code :
>>>
>>>
>>> double midiToFreq(double note)
>>>
>>> {
>>>
>>>     return 440.0 * pow(2.0, (note-69.0)/12.0);
>>>
>>> }
>>>
>>>
>>> float midiToFreq2(float note)
>>>
>>> {
>>>
>>>     return 440.0f * powf(2.0f, (note-69.0f)/12.0f);
>>>
>>> }
>>>
>>>
>>> int main()
>>>
>>> {
>>>
>>>     for (int i = 48; i < 84; i++) {
>>>
>>>         printf("pitch %d %f\n", i, midiToFreq(i));
>>>
>>>         printf("pitch %d %f\n", i, midiToFreq2(i));
>>>
>>>     }
>>>
>>> }
>>>
>>> correctly gives :
>>>
>>> pitch 48 130.812783
>>> pitch 48 130.812775
>>> pitch 49 138.591315
>>> pitch 49 138.591324
>>> pitch 50 146.832384
>>> pitch 50 146.832382
>>> pitch 51 155.563492
>>> pitch 51 155.563492
>>> pitch 52 164.813778
>>> pitch 52 164.813782
>>> pitch 53 174.614116
>>> ….
>>>
>>> when compiled with a C compiler and incorrectly gives the following when
>>> compiled with emcc and displayed in JS :
>>>
>>> pitch 48 130.812783
>>> pitch 48 130.812783
>>> pitch 49 138.591315
>>> pitch 49 136.604359
>>> pitch 50 146.832384
>>> pitch 50 148.968110
>>> pitch 51 155.563492
>>> pitch 51 155.563492
>>> pitch 52 164.813778
>>> pitch 52 162.450876
>>> pitch 53 174.614116
>>> pitch 53 177.153937
>>> pitch 54 184.997211
>>>
>>> When could be the reason for this strange behavior of the powf function ?
>>>
>>> Thanks.
>>>
>>> Stéphane Letz
>>>
>>>  --
>>> You received this message because you are subscribed to the Google
>>> Groups "emscripten-discuss" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
> You received this message because you are subscribed to the Google Groups
> "emscripten-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to