Nutzung von pow10

#3353175
Lesenswert?

Ich wollte mir eigentlich gerade ein paar Zehnerpotenzen in einer 
Lookup-Table speichern, da das generische pow() zu viel Platz braucht, 
bekam beim kompilieren aber den Fehler:
1
main.h:36:24: warning: built-in function ‘pow10’ declared as non-function [enabled by default]
2
 const uint16_t __flash pow10[] = {

Dachte ich mir nun also 'schön, bringt die Toolchain wohl schon mit.' 
Aber doch nicht so ganz:
1
main.c:229:85: error: called object ‘pow10’ is not a function or function pointer
2
         […] -= pow10(menuepos-1);

Die Suche nach einem Header o.ä. zu dieser Funktion brachte mich auch 
nicht wirlich weiter:
1
> ack-grep pow10 /usr/lib/gcc/ /usr/lib/avr
2
/usr/lib/gcc/avr/4.8.1/plugin/include/builtins.def
3
388:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
4
389:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
5
390:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)

Hat jemand einen Tipp zur Verwendung für mich?

Danke.
#3353536
Lesenswert?

Danke, aber hilft mir so auch erstmal nicht weiter:
1
> cat main.c
2
#define _GNU_SOURCE 
3
#include <math.h>
4

5
int main (void) {
6
    double foo = 2;
7
    double bar;
8
    bar = pow10(foo);
9
}
10
> avr-gcc -c -mmcu=attiny461 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -Wall -Wextra -Wpedantic -Wstrict-prototypes -Wa,-adhlns=./main.lst  -std=gnu99 -Wundef -MMD -MP -MF .dep/main.o.d main.c -o main.o 
11
main.c: In function ‘main’:
12
main.c:7:5: warning: implicit declaration of function ‘pow10’ [-Wimplicit-function-declaration]
13
     bar = pow10(foo);
14
     ^
15
main.c:7:11: warning: incompatible implicit declaration of built-in function ‘pow10’ [enabled by default]
16
     bar = pow10(foo);
17
           ^
18
main.c:6:12: warning: variable ‘bar’ set but not used [-Wunused-but-set-variable]
19
     double bar;
20
            ^
#3353628
Lesenswert?

> paar Zehnerpotenzen in einer Lookup-Table speichern

Welche?

Die Frage ist nämlich auch, ob du dir für die kleinen 10-er Potenzen 
überhaupt den Luxus eines double antun willst.

> ... avr-gcc -c -mmcu=attiny461 ....
Sicher, dass du überhaupt Floating Point haben willst?
Oder reicht dir nicht einfach nur eine Tabelle, die aus den Werten 1, 
10, 100, 1000, 10000 als uint16_t besteht?
Dann nenn die Funktion ganz einfach nicht pow10, wenn dieser Name 
(unzulässigerweise) schon vom gcc belegt ist, sondern irgendwie anders, 
und alles ist gut.


Wozu brauchst du das überhaupt?
#3353646
Lesenswert?

Karl Heinz Buchegger schrieb:
>> ... avr-gcc -c -mmcu=attiny461 ....
> Sicher, dass du überhaupt Floating Point haben willst?
> Oder reicht dir nicht einfach nur eine Tabelle, die aus den Werten 1,
> 10, 100, 1000, 10000 als uint16_t besteht?

Genau die habe ich auch:
1
const uint16_t __flash powten[] = {
2
    10000,
3
     1000,
4
      100,
5
       10,
6
        1
7
};
Dass sie "rückwärts" ist spart mit in dem Fall sogar eine Substraktion.

Mir ging es mehr um das generelle, falls ich das mal verwenden möchte, 
wie es dann tut – also Lernen für die Zukunft, nicht für den aktuelle 
Fall.
Persönliche Seite #3353648
Lesenswert?

Moritz A. schrieb:
> main.c:7:5: warning: implicit declaration of function ‘pow10’
> [-Wimplicit-function-declaration]

Also ist pow10 nicht in math.h enthalten. Damit wird vom Compiler

der Funktionsprototyp int pow10(int) angenommen.

Und das wiederum erklärt den Folgefehler:

> main.c:7:11: warning: incompatible implicit declaration of built-in function 
‘pow10’ [enabled by default]


Dir fehlt der passende Prototyp.

Mal in den Headerdateien gestöbert, wo pow10 deklariert wird?
#3353658
Lesenswert?

Rufus Τ. Firefly schrieb:
> Mal in den Headerdateien gestöbert, wo pow10 deklariert wird?

Genau das habe ich ja versucht, aber nix gefunden:

Moritz A. schrieb:
> Die Suche nach einem Header o.ä. zu dieser Funktion brachte mich auch
> nicht wirlich weiter:
1
> ack-grep pow10 /usr/lib/gcc/ /usr/lib/avr
2
/usr/lib/gcc/avr/4.8.1/plugin/include/builtins.def
3
388:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
4
389:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
5
390:DEF_EXT_LIB_BUILTIN    (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)

Rufus Τ. Firefly schrieb:
> der Funktionsprototyp int pow10(int) angenommen.

Ganz am Anfang war es auch int/int, nur nach dem Hinweis auf 
http://linux.die.net/man/3/pow10 hatte ich es auf double geändert. Der 
Fehler blieb der gleiche.
Gast #3354053
Lesenswert?

Mit C++ kann man sich seine eigene "pow" -Funktion definieren die zur 
Compile-Zeit läuft und somit das Ergebnis in den Flash gepackt werden 
kann:
1
#include <iostream>
2
#include <cstdint>
3

4
template <typename T>
5
constexpr T staticPow (T a, unsigned long long b) {
6
        return b == 0 ? 1 : a * staticPow (a, static_cast<decltype (b)> (b-1));
7
}
8

9
constexpr uint16_t powten [] = {
10
        staticPow (10, 4), staticPow (10, 3), staticPow (10, 2), staticPow (10, 1) };
11

12
int main () {
13
        for (auto x : powten)
14
                std::cout << x << std::endl;
15
}

Das iostream und std::cout Zeug ist nur zur Demonstration. Das constexpr 
an der Array-Definition stellt sicher dass die Berechnung vom Compiler 
durchgeführt wird und nur das Ergebnis im Programm landet. Dank dem 
Template funktioniert das auch mit allen numerischen Typen wie integer, 
float etc.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren