• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wielokąty foremne - zaokrąglanie wyników

Object Storage Arubacloud
0 głosów
116 wizyt
pytanie zadane 30 kwietnia 2020 w C i C++ przez Lukas Hajduga Użytkownik (830 p.)

Witam ! 

Mam poważny problem z zadaniem o wielokątach foremnych z C++. Program ma liczyć pole n-kąta, długość najkrótszej przekątnej oraz najdłużej i promień okręgu opisanego i wpisanego w ten wielokąt o boku długości a oraz podawać wynik z dokładnością do k miejsc po przecinku oraz poprawnie zaokrąglać wyniki. Problem w tym że dla kilku przykładów program działa idealnie i wypisuje poprawne dane ale dla niektórych wyniki są odchylone i jak mi się wydaje jest to spowodowane zaokrąglaniem liczb które nie są zaokrąglane poprawnie. Tutaj jest kod może znalazła by się jakaś osoba, która pomogła by to rozwiązać bardzo ważna sprawa.

#include <iostream>
#include <bits/stdc++.h>
#include <iomanip>
#include <math.h>

using namespace std;

long double polyarea(double n, double a) 
{ 
    if (a < 0 && n < 0) 
        return -1; 
  
    return (a * a * n) / (4 * tan((180 / n) * M_PI / 180)); 
} 

long double polyDiagonalShortest(double n, double a) 
{   
    if (a < 0 && n < 0) 
        return -1; 

    return 2 * a * sin((((n - 2) * 180) / (2 * n)) * M_PI / 180); 
} 

long double polyDiagonalLongest(int n, double a, double r) 
{
	if(n%2 != 0)
		return 2*r * cos(M_PI/n);
	else	
		return 2*r;		
}

long double polyRadius(float n, double a)
{
	return a/(2*sin(M_PI/n));
}

long double triangleHeight(float n, double a)
{
	return (a/2)*1/tan(M_PI/n);
}

long double roundNum(float number, float k)
{
	//return (number * (10*(10*k)))/(10*(10*k));
	return ((long double)(number*(10*(10*k))))/(10.0*(10*k));
}

int main()
{	
	int n, k;
	double a;
	
	cin >> n;
	cin >> k;
	cin >> a;	
	
	cout << fixed << setprecision(k) << roundNum(polyarea(n,a), k) << " ";	
	cout << fixed << setprecision(k) << roundNum(polyRadius(n,a), k) << " ";
	cout << fixed << setprecision(k) << roundNum(triangleHeight(n,a), k) << " ";
	cout << fixed << setprecision(k) << roundNum(polyDiagonalShortest(n,a), k) << " ";
	cout << fixed << setprecision(k) << roundNum(polyDiagonalLongest(n,a,polyRadius(n,a)), k);
		
	return 0;
}

Byłbym bardzo bardzo wdzięczny gdyby kotś szybko odpowiedział. Z góry dziękuje za pomoc i pozdrawiam wszystkich :)))))))))

 

Oto przykłady dla których program nie działa poprawnie:

Wejście: 17 5 1
Wyjście: 22.73549 2.72110 2.67476 1.96595 5.34953

Oczekiwane wyjście:  22.73549 2.72110 2.67476 1.96595 5.41898

komentarz 30 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Może wynikać po prostu z charakterystyki liczb zmiennoprzecinkowej.
komentarz 30 kwietnia 2020 przez Lukas Hajduga Użytkownik (830 p.)
A jest jakiś sposób aby to naprostwoać ?
komentarz 30 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Przy założeniu, że od strony matematyki wszystko jest okey, musisz wyłapać miejsce utraty precyzji.
komentarz 30 kwietnia 2020 przez Lukas Hajduga Użytkownik (830 p.)

oto jest wynik zaokrąglony  - 5.34952734374999999993
a ten nie zaokrąglany -  5.34952750550977640387

komentarz 30 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Sama różnica jest spora. Masz z 3 miejsca gdzie możesz stracić, roundNum, polyDiagonalLongest, oraz polyRadius. Na początku przyjrzałbym się zapisowi matematycznemu, bo łatwiej go naprawić. Możesz również doczytać o epsilonie.

1 odpowiedź

0 głosów
odpowiedź 30 kwietnia 2020 przez TOM_CPP Pasjonat (22,640 p.)

Stosujesz nieprawidłowy wzór na obliczanie największej przekątnej. Użyj:

double polyDiagonalLongest( int n , double a )
{  
    return a/(2.0*sin(M_PI/(2.0*static_cast<double>(n))));
}

 

komentarz 30 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Dlaczego rzutujesz na double? Nie ma to znaczenia, i tak będzie doublem.

Podobne pytania

+1 głos
2 odpowiedzi 1,610 wizyt
pytanie zadane 23 lipca 2020 w C i C++ przez ten_tomek Nowicjusz (160 p.)
0 głosów
3 odpowiedzi 1,570 wizyt
pytanie zadane 23 marca 2017 w C i C++ przez Undisputed Gaduła (3,040 p.)
0 głosów
1 odpowiedź 363 wizyt
pytanie zadane 5 grudnia 2022 w C i C++ przez piotr_domanski Bywalec (2,080 p.)

92,540 zapytań

141,383 odpowiedzi

319,481 komentarzy

61,928 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...