Sinusfunktion (Schleifen)
Schreiben Sie ein Programm, das die Sinusfunktion im Bogenmaß annähert.
Verwenden Sie für sin(x) die Näherungsformel
sin(x) ? x - x3/3! + x5/5! - x7/7! + ... - ...
Dabei bezeichnet n! die Fakultätsfunktion n! = 1 * 2 * 3 * ... * n.
Wenn Sie die jeweiligen Potenzen und Fakultäten aus denjenigen der vorangehenden Summanden berechnen, sparen Sie ein Vielfaches an Rechenleistung.
0 Kommentare
5 Lösung(en)
package eu.gressly.hw.iteration.sinus;
import java.util.Scanner;
/**
* Berechne den Sinus einer eingegebenen Zahl im Bogenmaß (360 Grad = 2 Pi).
* @author Philipp Gressly (phi@gressly.ch)
*/
/*
* History: first Implementation: May 21, 2010
* Bugs :
*/
public class Sinus {
public static void main(String[] args) {
new Sinus().top();
}
void top() {
double x, y;
x = einlesen("Zahl x");
y = sinus(x, 5);
System.out.println("sin(" + x + ") = " + y);
}
double sinus(double x, int iterationen) {
double resultat;
double zaehler;
double nenner;
double exponent;
int vorzeichen;
resultat = 0;
zaehler = x; // x, x^3, x^5, ...
nenner = 1; // 1!, 3!, 5!,
exponent = 1; // 1, 3, 5, ...
vorzeichen = 1; // 1, -1, 1, -1, ...
while(iterationen > 0) {
resultat = resultat + (vorzeichen) * zaehler / nenner;
zaehler = zaehler * x * x;
vorzeichen = -vorzeichen;
nenner = nenner * (exponent + 1) * (exponent + 2);
exponent = exponent + 2;
iterationen = iterationen - 1;
}
return resultat;
}
Scanner sc = new Scanner(System.in);
double einlesen(String input) {
System.out.println("Bitte " + input + " eingeben: ");
return sc.nextDouble();
}
} // end of class Sinus
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
# @autor Philipp Gressly Freimann
# 18. Jan 2012
#
# Aufgabe programmieraufgaben.ch
# Sinus
def pi()
return 3.1415926535897932384626433832795028841972
end
def sin(winkel)
winkel = winkel % (2 * pi())
resultat = winkel
altesResultat = resultat - 1 # ungleich resultat
winkelQuadrat = winkel * winkel
vorzeichen = 1 # (+1), (-1), (+1), (-1), ...
n = 2 # für Fakultaeten
zaehler = winkel # ungerade Potenzen des Winkels
nenner = 1 # Fakultät
while(altesResultat != resultat) do
altesResultat = resultat
vorzeichen = - vorzeichen
zaehler = zaehler * winkelQuadrat
nenner = nenner * n * (n+1)
# iteriere increment "resultat" um (±) winkel^(2n-1) / (2n-1)!
resultat = resultat + vorzeichen * zaehler / nenner
n = n + 2
end
return resultat
end
def hauptprogramm()
winkel = einlesenWinkel();
sinus = sin(winkel);
print "Sin von #{winkel} ist #{sinus}.\n"
print "Math.sin von #{winkel} ist #{Math.sin(winkel)}\n"
end
def einlesenWinkel()
print "Bitte Winkel (im Bogenmaß) eingeben: "
return STDIN.gets.to_f
end
# start
hauptprogramm()
Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)
Math.factorial = function(num) {
let out = 1, i;
for (i = 1; i <= num; i++) out *= i;
return out;
}
function sineApproximation(angle, steps = 5) {
let res = 0,
i = 1,
sign = 1;
while (steps > 0) {
res += sign * ((angle ** i) / Math.factorial(i));
sign *= -1;
i = i + 2;
steps--;
}
return res;
}
let alpha = 0.8;
console.log (sineApproximation(alpha, 2));
console.log (sineApproximation(alpha));
console.log (sineApproximation(alpha, 10));
console.log (Math.sin(alpha));
Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)
// NET 6.x | C# 10.x | VS-2022
IEnumerable<int> Fac(int n) {
var r = 1;
for (int i = 1; i <= n; i++)
yield return r *= i;
}
double SinApprox(double angle, int steps = 5) {
var fac = Fac(steps * 2 - 1).ToList();
var sum = 0.0;
var sgn = 1;
for (var i = 1; i < steps * 2; i += 2) {
sum += sgn * Math.Pow(angle, i) / fac[i - 1];
sgn *= -1;
}
return sum;
}
Console.WriteLine(SinApprox(0.3));
Console.WriteLine(SinApprox(0.8));
Lösung von: Jens Kelm (@JKooP)
// C++ 14 | VS-2022
#include <iostream>
#include <vector>
std::vector<int> fac_iter(int n) {
std::vector<int> v;
auto r{ 1 };
for (auto i{ 1 }; i <= n; i++)
v.push_back(r *= i);
return v;
}
double sin_approx(double angle, int steps = 5) {
const auto fac{ fac_iter(steps * 2 - 1) };
auto sum{ 0.0 };
auto sgn{ 1 };
for (auto i{ 1 }; i < steps * 2; i += 2) {
sum += sgn * pow(angle, i) / fac[static_cast<long long>(i) - 1];
sgn *= -1;
}
return sum;
}
int main() {
std::cout << sin_approx(0.3) << "\n";
std::cout << sin_approx(0.8) << "\n";
std::cout << sin_approx(0.8, 2) << "\n";
}
Lösung von: Jens Kelm (@JKooP)
Verifikation/Checksumme:
sin(0.8) = 0.7173561...
sin(0.3) = 0.2955202...
Das Programm sollte bereits bei fünf Iterationen ca. sieben Nachkommastellen liefern.
Aktionen
Neue Lösung hinzufügen
Bewertung
Durchschnittliche Bewertung:
Meta
Zeit: | 1 |
Schwierigkeit: | k.A. |
Webcode: | g5cx-nzxg |
Autor: | Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch) |