An die 'Matheisten': Problem mit nte-Wurzel

Für allgemeine Fragen zur Programmierung mit PureBasic.
Omi
Beiträge: 143
Registriert: 25.03.2013 09:59

An die 'Matheisten': Problem mit nte-Wurzel

Beitrag von Omi »

Hallo zusammen.

Kennt von Euch jemand ein nicht-iteratives, einfaches Verfahren um die 'nte Wurzel' korrekt zu berechnen (ohne Vorzeichen-Trickserei :wink: ).

Für jedes ungerade 'n' sind ja negative Radikanden möglich, die in vielen Programmiersprachen und allen Tabellenkalkulationen durch =POTENZ( Radikand;1/n) funktionieren.
PureBasic macht es sich einfach und erlaubt negative 'numbers' nur bei ganzzahligen Exponenten.
Auch die Exp - Ln - Kombi funktioniert, hier verständlicherweise, nicht.
Beispiel:

Code: Alles auswählen

n.i= 3
x.i= 8
;ergibt korrekt 2 ...
Debug Pow( x, 1 / n )
Debug Exp( Log(x) / n )

x= -8
;sollte -2 ergeben, liefert NaN...
Debug Pow( x, 1 / n )
Debug Exp( Log(x) / n )
Grüße Charly
Zuletzt geändert von Omi am 27.05.2017 06:37, insgesamt 1-mal geändert.
PureBasic Linux-API-Library: http://www.chabba.de
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: An die 'Matheisten': Problem mit nte-Wurzel

Beitrag von NicTheQuick »

Ungerade Wurzeln von negativen Zahlen sind eigentlich ein Sonderfall. Bau dir eine kleine Fallunterscheidung, die überprüft, ob n ungerade ist und x negativ. Dann zieh die n-te Wurzel aus dem Absolutwert von x und füge am Ende das Minus nochmal dazu.
Bild
Omi
Beiträge: 143
Registriert: 25.03.2013 09:59

Re: An die 'Matheisten': Problem mit nte-Wurzel

Beitrag von Omi »

Danke Nic,
das wär auch mein 'Backup' gewesen.

Ich hab dafür meine Funktion mal 'zusammengestrichen'. Es wird jetzt auch ein negativer Radikand bei ungeradzahligem Wurzelexponent 'n' ohne 'NaN' berechnet. Alle anderen "echten" Fehler sollten wie bisher beim gängigen Verfahren mit Pow(Number, 1 / Power) 'NaN' oder 'Division by zero' (n=0) liefern ...

Code: Alles auswählen

Procedure.d nthRoot(Radicand.d, n.i)
	Protected.i Sign= Sign(Radicand)
	
	If Sign = -1 And (n & 1)
		ProcedureReturn Pow( Abs( Radicand ), 1 / n ) * Sign
	Else
		ProcedureReturn Pow( Radicand, 1 / n )
	EndIf
EndProcedure

Debug nthRoot(-27, 3)
Debug nthRoot(81, 4)
Debug nthRoot(-16, 4); NaN
Debug nthRoot(-16, 0); bang
Gruß Charly
PureBasic Linux-API-Library: http://www.chabba.de
Antworten