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] 
> <javascript:>> 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] <javascript:>.
>> 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