Skip to main content
iforce2d
Associate III
May 19, 2021 9:33 AM UTC
Solved

atanf function not working?

Can anyone tell me why the value of 'c' here should be NaN ??

On other platforms I get the same result for 'a' and 'c', as expected.

#include <math.h>
 
float a = atanf( -1.0f ); // returns -0.785398185
 
float b = -1.0f;
float c = atanf( b ); // returns NaN

0693W00000AOtLbQAL.png 

I'm using STM32CubeIDE v1.4.0 on Linux.

Target is F103RCT6

This topic has been closed for replies.
iforce2d
iforce2dBest answer
Associate III
May 22, 2021 1:38 AM UTC

Okay this is embarrassing.

There was no difference between C and C++ so I spent all morning slowly removing things from my (rather large) project, only to discover this little gem in some 'helper' code I hadn't looked at for a very long time:

float fabsf( float f ) {
	if ( f >= 0 )
		return f;
	return f;
}

I don't recall making this, or why it was even necessary to make my own in the first place, or how I could have screwed it up and not suffered any problems until now, in over a year of working on this project.

But anyway, for some reason atanf finds it necessary to call fabsf (why??), but only in the case where the operand is a variable, not a literal, ie:

float a = atanf( -1.0f ); // does NOT call fabsf
 
float b = -1.0f;
float c = atanf( b ); // calls my broken fabsf

Thanks for the assistance Jan, sorry for the weird screwup.

8 replies

waclawek.jan
Super User
May 20, 2021 9:17 PM UTC

Is there any difference if you qualify a and c as volatile?

JW

iforce2d
iforce2dAuthor
Associate III
May 21, 2021 12:05 AM UTC

No, same result.

waclawek.jan
Super User
May 21, 2021 12:21 AM UTC

Show disasm.

My try went like

 volatile float a = atanf( -1.0f ); // returns -0.785398185
 8000214:	4b10 	ldr	r3, [pc, #64]	; (8000258 <main+0x60>)
 8000216:	9300 	str	r3, [sp, #0]
 
 float b = -1.0f;
 volatile float c = atanf( b ); // returns NaN
 8000218:	9301 	str	r3, [sp, #4]
 
 

so obviously the same value stored into both a and c (both declared as local, that's why are they on stack).

The constant is

 8000258:   bf490fdb   .word   0xbf490fdb

which is the same value as you've given (-0.785398185253)

JW

iforce2d
iforce2dAuthor
Associate III
May 21, 2021 8:26 AM UTC

hmm.... like this?

0693W00000AP95KQAT.png 

Not sure if it's relevant, but my project is using C++, not pure C.

make -j4 all 
 
arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m3 -std=gnu11 -g3 -DHAL_TIM_MODULE_ENABLED -DHAL_ADC_MODULE_ENABLED -DSTM32F103xE -DUSE_HAL_DRIVER -DDEBUG -DHAL_UART_MODULE_ENABLED -c -I../USB_DEVICE/Target -I../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I../Drivers/CMSIS/Include -I../Core/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -I../USB_DEVICE/App -I../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I../Drivers/STM32F1xx_HAL_Driver/Inc -I../Middlewares/ST/STM32_USB_Device_Library/Core/Inc -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/main.d" -MT"Core/Src/main.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o "Core/Src/main.o"
 
arm-none-eabi-g++ -o "F103RCT6.elf" @"objects.list" -mcpu=cortex-m3 -T"/home/chris/projects/stcubeide/F103RCT6/STM32F103RCTX_FLASH.ld" --specs=nosys.specs -Wl,-Map="F103RCT6.map" -Wl,--gc-sections -static --specs=nano.specs -mfloat-abi=soft -mthumb -u _printf_float -Wl,--start-group -lc -lm -lstdc++ -lsupc++ -Wl,--end-group
 
Finished building target: F103RCT6.elf

waclawek.jan
Super User
May 21, 2021 4:37 PM UTC

> Not sure if it's relevant, but my project is using C++, not pure C.

And what happens if you compile it as C?

JW

iforce2d
iforce2dAuthorBest answer
Associate III
May 22, 2021 1:38 AM UTC

Okay this is embarrassing.

There was no difference between C and C++ so I spent all morning slowly removing things from my (rather large) project, only to discover this little gem in some 'helper' code I hadn't looked at for a very long time:

float fabsf( float f ) {
	if ( f >= 0 )
		return f;
	return f;
}

I don't recall making this, or why it was even necessary to make my own in the first place, or how I could have screwed it up and not suffered any problems until now, in over a year of working on this project.

But anyway, for some reason atanf finds it necessary to call fabsf (why??), but only in the case where the operand is a variable, not a literal, ie:

float a = atanf( -1.0f ); // does NOT call fabsf
 
float b = -1.0f;
float c = atanf( b ); // calls my broken fabsf

Thanks for the assistance Jan, sorry for the weird screwup.

Tesla DeLorean
Guru
May 22, 2021 3:24 AM UTC

https://git.musl-libc.org/cgit/musl/tree/src/math/atanf.c

The compiler likely folds your first use as it is working with known constants.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
waclawek.jan
Super User
May 22, 2021 7:52 AM UTC

Great catch!

Thanks for coming back with the solution. Please select your post as Best so that the thread is marked as solved.

JW