[Spoed aub] Rekenfuncties werken niet goed, kan iemand mij aub snel helpen?

Status
Niet open voor verdere reacties.

turbojohn

Gebruiker
Lid geworden
26 jun 2007
Berichten
262
:thumb:Hoi,

Ik heb een vraagje. Ik moet voor school een 'complexe' rekenmachine maken in c++ en die heb ik bijna klaar, behalve dat onderstaande functies een foute waarde doorgeven. Nu heb ik (zoals je wel kunt zien) wat met static_cast lopen rommelen, omdat ik dacht dat dát het probleem was, maar de functies werken nogn iet. Kan iemand mij helpen?

Alvast hartelijk bedankt, want dan werkt mijn rekenmachine 100% en kan ik hem inleveren.

Code:
double Complex::geefArgument(int a, int b)   //werkt nog niet
        {
        double c = static_cast<double>(a);
        double d = static_cast<double>(b);
        return (atan2(d,c));  //  arctan(b/a)
        }
double Complex::geefA(int modulus, int argument)  //werkt niet
        {
          return (modulus*(static_cast<int>(cos(static_cast<double>(argument)))));
        }
int Complex::geefB(int modulus, int argument)     //werkt nog niet
        {
          return (modulus*(sin(argument)));
        }
 
Hoe bedoel je "werkt niet" ? Met dit stukje code kan ik vrij weinig :confused:
 
Snap ik;)

Ehm, ik heb een GUI met een complex invulvlak en een polair invulvlak.
Als ik aanvink: complex->complex en daarna bijv. + aanklik, dan moet hij de ingevulde getallen (bijv. 3+4i en 4+6i) optellen. Dat werkt. Maar bij vermenigvuldigen of delen moet deze getallen eerst omgezet worden naar xx<x graden, of wel polair.
Daarvoor zijn de functies geefargument etc etc er.

Rekenregels hierbij zijn:
complex -> polair omzetten:
Modulus = wortel van a² + b²
argument = artanges van (b / a) --> daarvoor dus de functie atan2()

polair->complex:
a = modulus * cosinus(argument)
b = modulus * sinus(argument)

Ik hoop dat bovenstaande dingen je iets zeggen?

De functies krijgen dus 2 getallen binnen en moeten die omrekenen.
de functie

Code:
double Complex::geefArgument(int a, int b)   //werkt nog niet
        {
        double c = static_cast<double>(a);
        double d = static_cast<double>(b);
        return (atan2(d,c));  //  arctan(b/a)
        }
Moet er dus voor zorgen dat er de arctanges van int b / int a wordt uitgerekend en teruggegeven. Maar dat werkt niet, er komt geen zinnig antwoord uit. Dit omdat ik denk dat atan2() met het type double werkt en ik intgetallen binnenhaal.
Hoe kan ik dit oplossen?

Is het zo duidelijk?
Alvast hartelijk bedankt voor je hulp!
 
Maar dat werkt niet, er komt geen zinnig antwoord uit. Dit omdat ik denk dat atan2() met het type double werkt en ik intgetallen binnenhaal.

Dat zou geen probleem moeten zijn. Int-getallen worden automatisch "gewidend" naar doubles.

Ik heb het uitgeprobeerd en dit werkt gewoon:
Code:
#include <iostream>
#include <cmath>

using namespace std;

int main()
{
        int x;
        int y;
        cin >> x;
        cin >> y;
        cout << "arctan " << y << "/" << x << " = " << atan2(y,x) << endl;
 return 0;
}

frank@darkstar:~$ g++ -Wall -ansi -o atan atan.cpp
frank@darkstar:~$ ./atan
-10
10
arctan 10/-10 = 2.35619
frank@darkstar:~$ ./atan
10
-10
arctan -10/10 = -0.785398

Deze waarden kloppen volgens internet (ik heb even geen calculator met arctangens functie bij de hand).
 
Dit is bijbehorende code:

Code:
if(Layout->operation->ItemIndex == 0)

                                      {
                                       //afhandelen van operations, als er álleen complex gerekend moet worden
                                        switch(functie)
                                        {
                                        int antwoord;
                                        int hoek;
                                        case '+' :      antwoord = (invoercomplex +  invoercomplex2);
                                                        hoek = (invoerj + invoerj2);
                                                        Layout->Uitvoer_complex->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_b->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;
                                        case '-' :      antwoord = ((invoercomplex) -  (invoercomplex2));
                                                        hoek = ((invoerj) - (invoerj2));
                                                        Layout->Uitvoer_complex->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_b->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;
                                        case '*' :      {
                                                        int modulus1 = geefModulus(invoercomplex, invoerj); //werkt
                                                        int modulus2 = geefModulus(invoercomplex2, invoerj2); //werkt
                                                        int hoek1 = geefArgument(invoercomplex, invoerj);
                                                        int hoek2 = geefArgument(invoercomplex2, invoerj2);
                                                        int modulustotaal = (modulus1 * modulus2);
                                                        int hoektotaal = (hoek1 + hoek2);
                                                        //dan weer terug naar cartesiaans
                                                        antwoord = geefA(modulustotaal, hoektotaal);
                                                        hoek = geefB(modulustotaal, hoektotaal);
                                                        Layout->Uitvoer_complex->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_b->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;
                                                        }
                                        case '/' :
                                                        break;

                                         }
                                        }

Als de functie een double is, moet dan (bij int hoek1) de functiewaarde opgevangen worden in een double? (dus moet het dan double hoek1 worden)?
 
Laatst bewerkt:
Hoi,

Ik heb het geprobeerd volgens jouw methode, maar krijg iedere keer de foutmelding DOMAIN ERROR atan2.

Wat kan dat zijn? Dit doe ik:
Code:
int hoek1 = geefArgument(invoercomplex, invoerj);
3, 4

Functie:
Code:
float Complex::geefArgument(int a, int b)   //werkt nog niet
        {
        return atan2(b,a);  //  arctan(b/a)
        }


De declaraties zijn:
Code:
#include "GUI.h"
#include <iostream>
#pragma hdrstop
#include "complex.h"
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <sstream>
#include <fstream>
#include <cmath>
using namespace std;
//---------------------------------------------------------------------------

#pragma package(smart_init)
Wat doe ik / Borland fout?
 
Maar bij vermenigvuldigen of delen moet deze getallen eerst omgezet worden naar xx<x graden, of wel polair.
Daarvoor zijn de functies geefargument etc etc er.

Waarom moet dat? Is het verplicht om het op die manier op te lossen?
Zonder conversie naar polair is het toch wat makkelijker lijkt mij.
Stel z en w zijn twee complexe getallen
z = a + bi en w = c + di
dan is het produkt
zw = (ac-bd) + (bc+ad)i
en het quotient
z/w = (ac+bd)/(c^2+d^2) + i(bc-ad)/(c^2+d^2)

En met c^2 bedoel ik c tot de tweede macht (ookwel c kwadraat)

Edit: ik zal later ook nog even wat langer naar je code kijken
 
Laatst bewerkt:
Ja dat weet ik wel. Maar ik moet ook polair naar cartesisch omzetten, dus heb ik atan2() nodig. Maar die wil dus niet werken.
Waar kan dat aan liggen, weet je dat misschien?

Alvast bedankt!;)
 
Ik heb geen compiler bij de hand, maar als je C++ gebruikt moet je wel even de C++ headers includen en niet de C headers. Vervang dus
Code:
#include <math.h>

door
Code:
#include <cmath>

Je zou ook de geoverloade functie atan2 van <valarray> kunnen gebruiken, klik hier
 
Hoi Niek_e, dan werken gelijk sqrt (wortel) enzo niet meer. math.h moet ik daarvoor wel gebruiken.


Hier de totale code,
Als ik bij case = '*' : hoek1 en hoek2 bekijk, dan werkt het wel (dus de rest eronder weglaten), dan krijg ik 12400 als uitkomst, heel vreemd overigens, maar toch wat.
Als ik de rest weer erbij zet (dus */ */ weghaal) dan (dit gaat alleen over case '*': ) werkt het niet meer en komt de domain_error er weer.

Hier mijn totale code, dat praat wat gemakkelijker;)
Code:
//---------------------------------------------------------------------------
#include "GUI.h"
#include <iostream>
#pragma hdrstop
#include "complex.h"
#include <stdio.h>
#include <math.h>
#include <string>
#include <sstream>
#include <fstream>

using namespace std;
//---------------------------------------------------------------------------

#pragma package(smart_init)

int invoercomplex, invoerj, invoercomplex2, invoerj2, invoermodulus, invoermodulus2, invoerhoek, invoerhoek2; //algemene (lokale) objecten, die de invoer moeten
char functie;
//lidfuncties



void Complex::rekenUit()
        {
        //beveiliging tegen de mogelijkheid dat er met een letter gerekend gaat worden. 
        if((Layout->a_complex->Text == "a" || Layout->b_complex->Text == "+/- b") || (Layout->Modulus->Text == "Mod." || Layout->Hoek_cartetisch->Text == "Hoek"))
        {
        Layout->Uitvoer_complex->Text = 0;
        Layout->Uitvoer_cartesisch->Text = 0;
        Layout->a_complex->Text = 0;
        Layout->b_complex->Text = 0;
        Layout->Modulus->Text = 0;
        Layout->Hoek_cartetisch->Text = 0;
        Layout->Uitvoer_b->Text = 0;
        Layout->Uitvoer_hoek->Text = 0;
        maakBufferleeg();
        }
        else
        {
        //rekenoperators bekijken
        
        if(Layout->plus->Font->Color == clLime)
                {
                        functie = '+';
                }

        if(Layout->min->Font->Color == clLime)
                {
                        functie = '-';
                }

        if(Layout->maal->Font->Color == clLime)
                {
                functie = '*';
                }

        if(Layout->delen->Font->Color == clLime)
                {
                functie = '/';
                }



//------------------inlezen oude waardes----------------------------------------
    ifstream leesuit("buffer.txt");
    
    leesuit >> invoercomplex;
    leesuit >> invoerj;
    leesuit >> invoermodulus;
    leesuit >> invoerhoek;
    leesuit.close();

//-----------------Iets ingevuld, maar nog geen antwoord? Dan waarde opslaan----

    if( ((Layout->operation->ItemIndex == 0 || Layout->operation->ItemIndex == 2 ) && Layout->Uitvoer_complex->Text == 0) || ((Layout->operation->ItemIndex == 1 || Layout->operation->ItemIndex == 3) && Layout->Uitvoer_cartesisch->Text == 0))
                        {
                        waardesOpslaan(0);
                        }
//---------------'HUIDIGE' waardes ophalen vanaf scherm-------------------------

                invoercomplex2 = StrToInt(Layout->a_complex->Text);
                invoerj2 = StrToInt(Layout->b_complex->Text);
                invoermodulus2 = StrToInt(Layout->Modulus->Text);
                invoerhoek2 = StrToInt(Layout->Hoek_cartetisch->Text);

                        //als de complexreken manier (alleen complex rekenen) is aangevinkt

                        if(Layout->isbutton->Font->Color == clRed)
                               {

                                                        //0 = complex -> complex
                                                        //1 = Polair -> polair
                                                        //2 = complex -> polair
                                                        //3 = polair->complex

                               if(Layout->operation->ItemIndex == 0)

                                      {
                                       //afhandelen van operations, als er álleen complex gerekend moet worden
                                        switch(functie)
                                        {
                                        int antwoord;
                                        int hoek;
                                        case '+' :      antwoord = (invoercomplex +  invoercomplex2);
                                                        hoek = (invoerj + invoerj2);
                                                        Layout->Uitvoer_complex->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_b->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;
                                        case '-' :      antwoord = ((invoercomplex) -  (invoercomplex2));
                                                        hoek = ((invoerj) - (invoerj2));
                                                        Layout->Uitvoer_complex->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_b->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;
                                        case '*' :      {
                                                        int modulus1 = geefModulus(invoercomplex, invoerj); //werkt
                                                        int modulus2 = geefModulus(invoercomplex2, invoerj2); //werkt
                                                        int hoek1 = geefArgument(invoercomplex, invoerj);
                                                        int hoek2 = geefArgument(invoercomplex2, invoerj2);
                                                        int modulustotaal = (modulus1 * modulus2);
                                                        int hoektotaal = (hoek1 + hoek2);
                                                        //dan weer terug naar cartesiaans
                                                        antwoord = geefA(modulustotaal, hoektotaal);
                                                        hoek = geefB(modulustotaal, hoektotaal);
                                                        Layout->Uitvoer_complex->Text = IntToStr(hoek1);
                                                        Layout->Uitvoer_b->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;
                                                        }
                                        case '/' :
                                                        break;

                                         }
                                        }
                         if(Layout->operation->ItemIndex == 1)   //polair->polair

                                      {
                                       //afhandelen van operations, als er álleen complex gerekend moet worden
                                        switch(functie)
                                        {
                                        int antwoord;
                                        int hoek;
                                        case '+' :
                                                        waardesOpslaan(1);
                                                        break;
                                        case '-' :
                                                        waardesOpslaan(1);
                                                        break;
                                        case '*' :      {
                                                        antwoord  = invoermodulus * invoermodulus2;
                                                        hoek = invoerhoek + invoerhoek2;
                                                        Layout->Uitvoer_cartesisch->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_hoek->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;
                                                        }
                                        case '/' :      antwoord = invoermodulus / invoermodulus2;
                                                        hoek = invoerhoek - invoerhoek2;
                                                        Layout->Uitvoer_cartesisch->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_hoek->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;

                                         }
                                        } //einde polair->polair
                         if(Layout->operation->ItemIndex == 2)   //complex->polair

                                      {
                                        //afhandelen van operations, als er álleen complex gerekend moet worden
                                        switch(functie)
                                        {
                                        int antwoord;
                                        int hoek;
                                        case '+' :
                                                        waardesOpslaan(1);
                                                        break;
                                        case '-' :
                                                        waardesOpslaan(1);
                                                        break;
                                        case '*' :      {
                                                        antwoord  = invoermodulus * invoermodulus2;
                                                        hoek = invoerhoek + invoerhoek2;
                                                        Layout->Uitvoer_cartesisch->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_hoek->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;
                                                        }
                                        case '/' :      antwoord = invoermodulus / invoermodulus2;
                                                        hoek = invoerhoek - invoerhoek2;
                                                        Layout->Uitvoer_cartesisch->Text = IntToStr(antwoord);
                                                        Layout->Uitvoer_hoek->Text = IntToStr(hoek);
                                                        waardesOpslaan(1);
                                                        break;

                                         }
                                        } //einde polair->polair
                }

}
}





void Complex::waardesOpslaan(int opslaanals)    //voor een langere tijd
{
        if(opslaanals != 1) //dus moet invoerwaardes opslaan
         {
        //opslaan (als er een cijfer ingevuld is)
        if((Layout->a_complex->Text != "a" && Layout->b_complex->Text != "+/- b") && (Layout->Modulus->Text != "Mod." && Layout->Hoek_cartetisch->Text != "Hoek"))
        {


                if(Layout->plus->Font->Color == clLime || Layout->min->Font->Color == clLime || Layout->maal->Font->Color == clLime || Layout->delen->Font->Color == clLime)
                {
                ofstream buffer("buffer.txt");
                invoercomplex2 = StrToInt(Layout->a_complex->Text);
                invoerj2 = StrToInt(Layout->b_complex->Text);
                invoermodulus2 = StrToInt(Layout->Modulus->Text);
                invoerhoek2 = StrToInt(Layout->Hoek_cartetisch->Text);
                buffer << invoercomplex2 << endl;
                buffer << invoerj2 << endl;
                buffer << invoermodulus2 << endl;
                buffer << invoerhoek2 << endl;
                buffer.close();
                }
        }
        else   //als geen van de situaties hierboven juist is, dus foute invoer
                {
                Layout->Uitvoer_complex->Text = "Verkeerde invoer";
                Layout->Uitvoer_complex->Font->Color = clRed;
                }
        }
        if(opslaanals == 1)
        {
        ofstream buffer("buffer.txt");
                invoercomplex2 = StrToInt(Layout->Uitvoer_complex->Text);
                invoerj2 = StrToInt(Layout->Uitvoer_b->Text);
                invoermodulus2 = StrToInt(Layout->Uitvoer_cartesisch->Text);
                invoerhoek2 = StrToInt(Layout->Uitvoer_hoek->Text);
                buffer << invoercomplex2 << endl;
                buffer << invoerj2 << endl;
                buffer << invoermodulus2 << endl;
                buffer << invoerhoek2 << endl;
                buffer.close();
        }

}
//----------------------OMREKENFUNCTIES-----------------------------------------
//reken cartesisch naar polair of omgekeerd
float Complex::geefModulus(int a, int b) //werkt
        {
          return sqrt(((a*a) + (b*b)));
        }
float Complex::geefArgument(int a, int b)   //werkt nog niet
        {
        return (atan2(b,a));  //  arctan(b/a)
        }
float Complex::geefA(int modulus, int argument)  //werkt niet
        {

          return modulus*cos(argument);
        }
float Complex::geefB(int modulus, int argument)     //werkt nog niet
        {
          return modulus*sin(argument);
        }


//----------------WISSEN VAN WAARDES--------------------------------------------
//om alle variabelen te wissen nadat een rekenfunctie is uitgevoerd dient onderstaande functie gebruikt te worden
//deze moet nog even aangepast worden, werkt nog niet...

void Complex::maakBufferleeg()
        {
        ofstream buffer("buffer.txt", ios::trunc);
       
        }



//setters
void Complex::setinvoer_a(float a)
        {
                invoer_a = a;
        }
void Complex::setinvoer_b(float b)
        {
                invoer_b = b;
        }
void Complex::setinvoer_mod(float mod)
        {
                invoer_mod = mod;
        }
void Complex::setinvoer_hoek(float hoek)
        {
                invoer_hoek = hoek;
        }
void Complex::setoperator(float op)
        {
                operatorr = op;
        }

//getters
int Complex::getinvoer_a()
        {
                return invoer_a;
        }
int Complex::getinvoer_b()
        {
                return invoer_b;
        }
int Complex::getinvoer_mod()
        {
                return invoer_mod;
        }
int Complex::getinvoer_hoek()
        {
                return invoer_hoek;
        }
int Complex::getoperator()
        {
                return operatorr;
        }
 
De waarde van atan2() is een gebroken getal het is wel handig om het resultaat in
een double op te slaan. Als je een int gebruikt wordt het afgerond op een
geheel getal en dan geeft mijn compiler ook een warning.

De volgende code werkt bij mij wel.
Code:
#include <iostream>
#include <cmath>
using namespace std;


double
geefArgument(int a, int b)
{
  //cout << "atan2(b,a) = atan2("<<b<<","<<a<<") = "   << atan2(b,a) <<"  " <<(int)atan2(b,a) << endl;
  return atan2(b,a);  //  arctan(b/a)
}


int
main()
{
 int a,b;
 double argument;

 cout << "geef a:" << endl;
 cin >> a;
 cin.ignore();

 cout << "geef b:" << endl;
 cin >> b;
 cin.ignore();

 argument = geefArgument(a,b);
 cout << "argument = " << geefArgument(a,b) << endl;
 return 0;
}

voorbeeld van uitvoer:
D:\>zatan
geef a:
1
geef b:
1
argument = 0.785398


D:\>zatan
geef a:
3
geef b:
5
argument = 1.03038

D:\>zatan
geef a:
3
geef b:
1
argument = 0.321751

D:\>zatan
geef a:
1
geef b:
-1
argument = -0.785398

Edit: Ik zal ook de code die je net gepost hebt bekijken

Edit2:Heb de code bekeken en kan niet zien wat er mis is.
De fout heb ik niet kunnen reproduceren aangezien ik alleen over de standaard header files beschik en niet over bijv. Gui.h. Misschien kan iemand anders je wel verder helpen.
 
Laatst bewerkt:
hoi,

Dat met atan2() werkt nu;) Had ergens een intverwerking staan, vandaar dat het delen moeilijk ging;)

Maar ik heb een ander vraagje. Als ik een polair getal om wil zetten naar een complex getal (bijv. 65<0,53 naar caresiaans (=56+33i) ) hoe kan ik dat dan het beste doen?
Intgetallen kennen geen komma's en de functie is 65.cos(0,53).
Kan ik dat met een float ofzo oplossen, en hoe dan?

Code:
 float antwoord = geefA(StrToFloat(Layout->Modulus->Text), StrToFloat(Layout->Hoek_cartetisch->Text));
                                                        float hoek = geefB(StrToFloat(Layout->Modulus->Text), StrToFloat(Layout->Hoek_cartetisch->Text));

                                                        Layout->Uitvoer_complex->Text = FloatToStr(antwoord);
                                                        Layout->Uitvoer_b->Text = FloatToStr(hoek);

Code:
float Complex::geefA(int modulus, float argument)  //werkt niet
        {

          return modulus*cos(argument);
        }
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan