The problematic case is our default - it seems troubling to have a big
warning on our default compilation settings. Yet, for the reasons mentioned
above, I'm not sure we can change that default.

I did add an entry on this to the FAQ meanwhile.

- Alon


On Sat, Jan 31, 2015 at 6:49 AM, Stéphane Letz <[email protected]> wrote:

> Why not then simply print a big warning when compiling the problematic
> case, and suggest to use the  PRECISE_F32 flag for proper results?
>
> Stéphane
>
> Le vendredi 30 janvier 2015 19:48:43 UTC+1, azakai a écrit :
>>
>> exp2f in MUSL is correct, but it *does* depend on precise float32
>> semantics. Doing the operations in JavaScript doubles leads to imprecision
>> and errors. That's why building with PRECISE_F32 makes it work.
>>
>> The confusing thing is that LLVM only switches to exp2f when optimizing.
>> But that is correct as well, exp2f is power of 2, which is faster to
>> compute than a generic Math.pow(x, y) with arbitrary x. So this made the
>> bug harder to track down, but LLVM is also doing the right thing here.
>>
>> Perhaps the only thing that is "wrong" is that emscripten does not have
>> PRECISE_F32 on by default. However, it increases code size by some 4% (on
>> bullet, which I tested now), and while its optimized well in firefox, it
>> still isn't in other browsers (box2d is almost 2x slower in chrome, 10%
>> slower in safari), so we should wait on them to improve before turning it
>> on by default.
>>
>> However, an argument could be made that we should turn PRECISE_F32 on in
>> debug builds or -O0 or something like that, so -O0 is guaranteed to have
>> the right semantics. But I'm not sure that's the right thing either.
>> Thoughts?
>>
>> - Alon
>>
>>
>> On Fri, Jan 30, 2015 at 6:40 AM, Stéphane Letz <[email protected]> wrote:
>>
>>> So in other words the musl "exp2f" implementation seems incorrect yes?
>>> Is the following code used :
>>>
>>> https://github.com/rofl0r/musl/blob/master/src/math/exp2f.c
>>>
>>> Should we do a bug report?
>>>
>>> Or do you consider using musl "exp2f" in optimized mode in Emcripten is
>>> the problem in the first place?
>>>
>>> Thanks.
>>>
>>> Stéphane Letz
>>>
>>> Le jeudi 29 janvier 2015 21:03:00 UTC+1, Alon Zakai a écrit :
>>>>
>>>> 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.
>>>
>>
>>  --
> 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