[C] Machtsverheffen werkt wel, maar niet overal??

Pagina: 1
Acties:
  • 290 views sinds 30-01-2008
  • Reageer

  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
Voor een schoolopdracht moet ik een C programmaatje schrijven dat aan de commandline 3 floats als input vraagt, en er vervolgens de abc-formule op los laat.

Omdat ik moet machtsverheffen en worteltrekken heb ik math.h ge-include.
Ter illustratie de bijbehorende code:
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <math.h>

float discriminant(float, float, float);
void bereken(float, float, float, float*, float*, float*);

main(){
    float input1, input2, input3;
    float a1, a2, d;
    
    printf("Voer 3 float-getallen in:\n");
    scanf("%f %f %f", &input1, &input2, &input3);
    bereken(input1, input2, input3, &a1, &a2, &d);
    printf("Discriminant is: %.2f\n",d);
}

float discriminant(float a, float b, float c){
    return pow(b,2) - 4*a*c;
}

void bereken(float a, float b, float c, float *getalA, float *getalB, float *D){
    *D = discriminant(a,b,c);
    if(*D == 0){
        *getalA = (-1*b + sqrt(*D))/(2*a);
    }
    if(*D > 0){
        *getalA = (-1*b + sqrt(*D))/(2*a);
        *getalB = (-1*b - sqrt(*D))/(2*a);
    }
}

Het vreemde is, dat de pow wel werkt in de functie discriminant, maar in de functie bereken krijg ik een foutmelding: undefined reference to 'sqrt'. Vervang in dit door 'pow' (zinloos, maar je weet nooit), dan is pow ineens ook een undefined reference geworden. Ik snap er helemaal niets van, omdat ik math.h netjes ge-include heb, en 't werkt weer wel in de functie determinant :?

Iemand een idee?

  • Tepel
  • Registratie: Juni 2006
  • Laatst online: 25-12-2025
SYNOPSISSQRT(3) Linux Programmer's Manual SQRT(3)

NAME
sqrt, sqrtf, sqrtl - square root function

SYNOPSIS
#include <math.h>

double sqrt(double x);
float sqrtf(float x);
long double sqrtl(long double x);

Link with -lm. <------

0x7F


  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
Ik snap je punt, maar waarom werkt pow() dan wel?!?

  • Tepel
  • Registratie: Juni 2006
  • Laatst online: 25-12-2025
Die werkt niet, alleen is je compiler niet verder gegaan denk ik zo. Ik zou zeggen check de return value eens
[edit]
Ok hij werkt wel, weet niet waarom. Gaat erom dat je prog wel werkt als je met -lm compiled.

[ Voor 31% gewijzigd door Tepel op 23-09-2006 14:27 ]

0x7F


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13-02 18:09
cbijlsma schreef op zaterdag 23 september 2006 @ 14:21:
Ik snap je punt, maar waarom werkt pow() dan wel?!?
Misschien een inline functie ? Ik kan me voorstellen dat een pow( x, 2 ) wordt geoptimaliseerd naar x * x.

[ Voor 16% gewijzigd door farlane op 23-09-2006 14:31 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Tepel
  • Registratie: Juni 2006
  • Laatst online: 25-12-2025
Aha! gevonden!
What we need here is a special compiler flag:

gcc -o pi -lm pi.c

"lm" tells it to link in the math libraries. Math libraries? Sure, you didn't think C by itself knows how to do arc tangents, did you? C by by itself doesn't know much. Most of its functions - the things you can use - come from external libraries that get linked in. How would you know when you need to use a special library? It's just something you have to learn. Usually, if there is a special linker flag, the man page will have told you. In the case of atan, it does not, so you just need to remember that you need "-lm" when you see "#include <math.h>" mentioned.
Dat ook weer opgelost

0x7F


  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
-lm was de uitkomst. Leuk, als je net 3 weken met C aan de slag bent >:)

Tepel: _/-\o_

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13-02 14:38
Tepel heeft geijk; je moet tegen de math library linken.

Dat de aanroep naar pow() wel werkt, komt waarschijnlijk doordat veel functies in math.h zijn geïmplementeerd als platformafhankelijke macro's (ten behoeve van de performance). Als je in C programmeert, moet je dingen altijd doen zoals voorgeschreven is en niet op de manier waarop het toevallig werkt, want daarmee kun je allerlei bugs introduceren.

Overigens is voor het berekenen van een kwadraat de pow() functie nogal zwaar materieel; schrijf dan liever gewoon b*b - 4*a*c. Verder hoor je de single precision varianten (powf(), sqrtf()) te gebruiken als je met floats rekent, anders introduceer je een hoop zinloze conversies. (Maar gebruik liever doubles, tenzij je een goede reden hebt om ruimte te besparen.)

  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
Ik zal me er eens in verdiepen. De reden dat ik floats gebruik is omdat het *moet* van de docent. Blijkbaar moeten we ermee leren werken en gaat ze over een week of wat opeens over doubles beginnen (zoals bij java het geval was :S).

offtopic:
De narigheid is ook een beetje dat het voorgeschreven boek uitverkocht is totdat het blok voorbij is, en over compilen gaan we het denk ik niet hebben...

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13-02 14:38
Het is niet echt fout om floats te gebruiken (maar je kunt je afvragen waarom je precisie zou opofferen, als je er geen goede reden voor hebt), maar gebruik dan ook de single-precision functies uit de math library.

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 13-02 20:06

Gerco

Professional Newbie

cbijlsma schreef op zaterdag 23 september 2006 @ 15:02:
en over compilen gaan we het denk ik niet hebben...
Dat wordt lastig testen dan of heeft je docent een c interpreter bij de hand? Voor je de code kan runnen zul je het wel moeten compilen :)

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • coenbijlsma
  • Registratie: Augustus 2004
  • Niet online
Ze gaat er voor het gemak vanuit dat we dat zelf wel uit kunnen zoeken. We hebben de naam van de IDE gekregen (Anjuta) en voor de rest moeten we het zelf uitzoeken...

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13-02 18:09
cbijlsma schreef op zaterdag 23 september 2006 @ 20:37:
Ze gaat er voor het gemak vanuit dat we dat zelf wel uit kunnen zoeken. We hebben de naam van de IDE gekregen (Anjuta) en voor de rest moeten we het zelf uitzoeken...
Anjuta gebruikt de GNU toolchain om applicaties te compileren ( configure / make / gcc/g++ )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 10-12-2025
cbijlsma schreef op zaterdag 23 september 2006 @ 15:02:
Ik zal me er eens in verdiepen. De reden dat ik floats gebruik is omdat het *moet* van de docent. Blijkbaar moeten we ermee leren werken en gaat ze over een week of wat opeens over doubles beginnen (zoals bij java het geval was :S).

offtopic:
De narigheid is ook een beetje dat het voorgeschreven boek uitverkocht is totdat het blok voorbij is, en over compilen gaan we het denk ik niet hebben...
Klein gokje: de docent heeft absoluut geen idee war hij het over heeft. Er is geen enkele gangbare CPU die enig voordeel heeft van floats. De laatste 10 jaar werkt iedereen native met 64 of 80 bits (en noemt dat double of long double). Floats zijn alleen nuttig als je er een paar miljoen van hebt, dan scheelt het geheugen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 27-01 12:55

Bergen

Spellingscontroleur

Je kunt natuurlijk ook je eigen machtsverheffunctie schrijven... Dan weet je ook zeker dat 't altijd werkt. ;)

  • dingstje
  • Registratie: Augustus 2002
  • Laatst online: 02-01-2024
Waarom zou je zelf een functie schrijven als er reeds standaard functies aanwezig zijn? Op jouw architectuur doet pow misschien niets anders dan x * x, maar op een andere architectuur is er misschien een instructie op de processor die 'über-1337-fast' machten kan uitvoeren. Als je de math library gebruikt zal die instructie dan ook effectief gebruikt worden op die architectuur, terwijl jouw functie altijd hetzelfde (en dus mogelijk de tragere variant) zal doen.

If you can't beat them, try harder


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 13-02 14:38
Ik mag hopen dat als je een über-1337-fast processor hebt die pow(x,2) sneller uitrekent dan mul(x,x), de compiler ook zo slim is om die pow-instructie te genereren voor de expressie x*x. Kortom, er is niet echt een reden om géén x*x te schrijven. Verder zou ik inderdaad overwegen om geheeltallige machten 'handmatig' uit te rekenen; de pow-functie is vooral nuttig voor niet-geheeltallige machten.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 13-02 18:09
Bergen schreef op zondag 24 september 2006 @ 02:21:
Je kunt natuurlijk ook je eigen machtsverheffunctie schrijven... Dan weet je ook zeker dat 't altijd werkt. ;)
Das een gebruikelijke misvatting onder programmeurs ... http://www.pragmaticprogrammer.com/

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1