math.hを使ったsqrt()

sqrt()の引数に変数を入れて使いたいのですが、

#include "math.h"
 

    double i = 2.0;
    i = sqrt(i);

 

とすると以下のようなエラーが出ます。

 

-I lib/FreeRTOS/Source/include -I lib/FreeRTOS/Source/portable/GCC/ARM_CM3 -I lib/Startup -I lib/Platform  -L ./lib -mcpu=cortex-m3 -mthumb NHD_C12832A1Z.o main.o stm32f10x_it.o lib/Startup/startup_stm32f10x_hd_nortos.o lib/lib.a -o bin\main.elf 
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.4.1/../../../../arm-none-eabi/lib/thumb2\libm.a(lib_a-w_sqrt.o): In function `sqrt':
w_sqrt.c:(.text+0x78): undefined reference to `__errno'
w_sqrt.c:(.text+0xa2): undefined reference to `__errno'
collect2: ld returned 1 exit status
cs-make: *** [bin\main.elf] Error 1
-I lib/FreeRTOS/Source/include -I lib/FreeRTOS/Source/portable/GCC/ARM_CM3 -I lib/Startup -I lib/Platform  -L ./lib -mcpu=cortex-m3 -mthumb NHD_C12832A1Z.o main.o stm32f10x_it.o lib/Startup/startup_stm32f10x_hd_nortos.o lib/lib.a -o bin\main.elf 
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.4.1/../../../../arm-none-eabi/lib/thumb2\libm.a(lib_a-w_sqrt.o): In function `sqrt':
w_sqrt.c:(.text+0x78): undefined reference to `__errno'
w_sqrt.c:(.text+0xa2): undefined reference to `__errno'
collect2: ld returned 1 exit status
cs-make: *** [bin\main.elf] Error 1
-I lib/FreeRTOS/Source/include -I lib/FreeRTOS/Source/portable/GCC/ARM_CM3 -I lib/Startup -I lib/Platform  -L ./lib -mcpu=cortex-m3 -mthumb NHD_C12832A1Z.o main.o stm32f10x_it.o lib/Startup/startup_stm32f10x_hd_nortos.o lib/lib.a -o bin\main.elf 
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.4.1/../../../../arm-none-eabi/lib/thumb2\libm.a(lib_a-w_sqrt.o): In function `sqrt':
w_sqrt.c:(.text+0x78): undefined reference to `__errno'
w_sqrt.c:(.text+0xa2): undefined reference to `__errno'
collect2: ld returned 1 exit status
cs-make: *** [bin\main.elf] Error 1
-I lib/FreeRTOS/Source/include -I lib/FreeRTOS/Source/portable/GCC/ARM_CM3 -I lib/Startup -I lib/Platform  -L ./lib -mcpu=cortex-m3 -mthumb main.o stm32f10x_it.o lib/Startup/startup_stm32f10x_hd_nortos.o lib/lib.a -o bin\main.elf 
c:/program files/codesourcery/sourcery g++ lite/bin/../lib/gcc/arm-none-eabi/4.4.1/../../../../arm-none-eabi/lib/thumb2\libm.a(lib_a-w_sqrt.o): In function `sqrt':
w_sqrt.c:(.text+0x78): undefined reference to `__errno'
w_sqrt.c:(.text+0xa2): undefined reference to `__errno'
collect2: ld returned 1 exit status
cs-make: *** [bin\main.elf] Error 1
 
代わりに

i = sqrt(2.0);

などとした場合はエラーは出ないのですが、設定に問題があるのでしょうか?
他の関数 sin()、 cos()は正常に動作しているようです。

よろしくお願いします。

Win XP 簡単版導入編で開発環境を作っています。

浮動小数点型がノンサポートだからだと思います

doubleは浮動小数点型ですが、STM32をはじめ、このクラスのマイコンの多くは、浮動小数点演算ユニットを内蔵していません。つまりdouble型の計算自体ができません。

前者のコードのエラーはそのためだと思います。後者は黙示的に整数型にキャストされているのではないでしょうか。

使ったことはないのですが、gccはソフトウェアで浮動小数点演算をシミュレートするライブラリを内蔵しているので、速度とプログラムサイズを犠牲にしても良いのであれば、これを使うという方法があります。

http://jr0bak.homelinux.net/~imai/linux/arm_gcc_badknowhow/arm_gcc_badknowhow-7.html

ここで解説がありますので読んでみてください。

 

出来ました

ありがとうございます。

サイトを読んでいて、gccオプション -lm を付ければよいという話を思い出して Makefileの一部を改造してできました!

その代わり、かなり遅くなりました。

なるほど

undefined reference だからリンク漏れだったんですね。

ビルドできて良かったです。

よろしければ教えていただきたいんですが、浮動小数点数の取り扱いは特に不具合無くできていますでしょうか?手順としてはmath.hのインクルードとコンパイルオプション(-lm)の指定だけですよね。

うまくいくようであれば、サンプルプログラムに加えたいと思います。

実際に行った事

正直細かいことはよくわからないのですが、単に-lmではなく以下のようにしています。

------------------------------------------------------------------------------------------------------------------------

make file 

71行目に
LDLIBS  += -lc -lm -lgcc
を追加

105行目付近を以下のように追加しています。
 
$(MAIN_OUT): $(MAIN_OBJS) $(START_UP) $(LINK_FWLIB)  
$(LD) $(LDFLAGS) $(TARGET_ARCH) $^ -o $@  $(LDLIBS)
$(MAIN_OUT): $(MAIN_OBJS) $(START_UP) $(LINK_FWLIB)  
$(LD) $(LDFLAGS) $(TARGET_ARCH) $^ -o $@  $(LDLIBS)
 
簡単な確認方法はCprintf が int型にしか対応していないので、douoble型は表示できないので、小数点以下は1000倍したりして工夫しています。
 
ex)
double n = 2.0;
n = sqrt(n);
cprintf("%d",(int)(n*1000));
 
結果:
1414
 
といった具合です。
 
------------------------------------------------------------------------------------------------------------------------
 
上記だけで動かない場合、これもあわせてみてください(あまり意味ないかもしれませんが・・・)
project -> properties -> C/C++ General -> path and symbols -> includesタブ -> Gnu C -> include directries に追加しています。
C:\Program Files\CodeSourcery\Sourcery G++ Lite\arm-none-eabi\lib\thumb2
C:\Program Files\CodeSourcery\Sourcery G++ Lite\lib\gcc\arm-none-eabi\4.4.1
 
 
------------------------------------------------------------------------------------------------------------------------
 

 

 
LDLIBS  += -lc -lm -lgcc
LDLIBS  += -lc -lm -lgcc

 

 

 
 
LDLIBS  += -lc -lm -lgcc

ありがとうございます

レポートありがとうございます。

こちらでも工夫してみて、makefile.inあたりでスイッチできるようにしてみたいと思います。