Moderators Kercyn Δημοσ. 17 Μαρτίου 2015 Moderators Δημοσ. 17 Μαρτίου 2015 Μπορείς να το πολλαπλασιάσεις με 10x, όπου x το πλήθος των ψηφίων που σε ενδιαφέρει, μετά να το κάνεις int και μετά πάλι float και επί 10-x. 1
bnvdarklord Δημοσ. 17 Μαρτίου 2015 Δημοσ. 17 Μαρτίου 2015 Ποιος ο λόγος να το βγάλεις; Στους υπολογισμούς που κανεις φαντάζομαι δεν έχει ιδιαίτερη σημασία, και όταν είναι να το τυπώσεις καπου συνήθως μπορεις να ορίσεις πόσα δεκαδικά σε ενδιαφέρουν(πχ στη printf).
we_will_rise Δημοσ. 17 Μαρτίου 2015 Δημοσ. 17 Μαρτίου 2015 Αν κατάλαβα καλά.. http://stackoverflow.com/a/554215/2546828
παπι Δημοσ. 17 Μαρτίου 2015 Μέλος Δημοσ. 17 Μαρτίου 2015 Ποιος ο λόγος να το βγάλεις; Στους υπολογισμούς που κανεις φαντάζομαι δεν έχει ιδιαίτερη σημασία, και όταν είναι να το τυπώσεις καπου συνήθως μπορεις να ορίσεις πόσα δεκαδικά σε ενδιαφέρουν(πχ στη printf). Ελα ντε,.. Θα φτάνει η ωρα. Βασικα ειναι πιο περιπλοκο το round που θελω.
gon1332 Δημοσ. 17 Μαρτίου 2015 Δημοσ. 17 Μαρτίου 2015 1) Μη χρησιμοποιείς float. Απλά δε μπορεί να γίνει σωστή αναπαράσταση. 2) Αν θες να κρατήσεις συγκεκριμένο αριθμό δεκαδικών θα μπορούσες να χρησιμοποιήσεις την ιδέα του bnvdarklord αλλά με συνδυασμό sprintf-sscanf και format identifier %g, οποίος, αν πας να κόψεις κάποια ψηφία από το δεκαδικό κομμάτι, στρογγυλοποιεί. Κάτι τέτοιο: sprintf(reg, float_format, lbfl);sscanf(reg, "%lf", &lbfl); Με ζωντανό παράδειγμα.
παπι Δημοσ. 17 Μαρτίου 2015 Μέλος Δημοσ. 17 Μαρτίου 2015 Ειναι πιο περιπλοκο αυτο που θελω. Δεν υπαρχουν const.
gon1332 Δημοσ. 17 Μαρτίου 2015 Δημοσ. 17 Μαρτίου 2015 Λόγω float έχεις θέμα. Τί ακριβώς θες να κάνεις; const;! Δε σε πιάνω.
imitheos Δημοσ. 17 Μαρτίου 2015 Δημοσ. 17 Μαρτίου 2015 Γενικά μπορείς να κόψεις όσα ψηφία θέλεις με τους τρόπους που προτάθηκαν. Σε κάποιες τιμές όμως δεν μπορείς να γλυτώσεις τα σκουπίδια λόγω του τρόπου αναπαράστασης. #include <stdio.h> #include <math.h> int main(void) { float lblf = 0.150000006; printf("%.12f\n", lblf); printf("%.12f\n", roundf(lblf * 100.f)); printf("%.12f\n", roundf(lblf * 100.f) / 100.f); printf("%.12f\n", round(lblf * 100.f) / 100.f); return 0; } Έξοδος: 0.150000005960 15.000000000000 0.150000005960 0.150000000000 Όπως βλέπουμε στην 2η γραμμή, το round παίζει κανονικά και βγάζει 15 αλλά μετά την διαίρεση ερχόμαστε ξανά στην αρχική κατάσταση επειδή η συγκεκριμένη τιμή δεν μπορεί να αναπαρασταθεί σωστά. Στην 4η γραμμή βλέπουμε πως αν χρησιμοποιήσουμε double, τότε παίρνουμε το σωστό αποτέλεσμα λόγω μεγαλύτερης ακρίβειας. Αν χρησιμοποιήσουμε ως αρχική τιμή το 0.160000006 που είναι πολύ καλύτερη τιμή βλέπουμε πως και πάλι σε float έχουμε πρόβλημα μετά τα 6-7 ψηφία. 0.160000011325 16.000000000000 0.159999996424 0.160000000000 Δυστυχώς η γενική σύσταση για FP είναι "μην χρησιμοποιείς ποτέ float" γιατί ο float έχει σκατά ακρίβεια.
gon1332 Δημοσ. 17 Μαρτίου 2015 Δημοσ. 17 Μαρτίου 2015 Γενικά μπορείς να κόψεις όσα ψηφία θέλεις με τους τρόπους που προτάθηκαν. Σε κάποιες τιμές όμως δεν μπορείς να γλυτώσεις τα σκουπίδια λόγω του τρόπου αναπαράστασης. ... Και αυτό φαίνεται ακόμη καλύτερα από εδώ (που λογικά ήθελε να αναπαραστήσει το 0.15): float lbfl = 0.15f; printf("lbfl = %.15f\n", lbfl); Εδώ για αποτελέσματα. 1
παπι Δημοσ. 17 Μαρτίου 2015 Μέλος Δημοσ. 17 Μαρτίου 2015 Εχω αυτοΗ αριθμοι δειχνουν σωστα το transformed space.Αυτο που θελω ειναι να κανω round το inital y ετσι ωστε να βγαινουν πιο "ωραιοι" οι αριθμοι.Να αυτο που κανω τωρα TextFormatProperties prps; this->pTextFormat->GetProperties(prps); float maxLabels = (this->rcAxis.top - this->rcAxis.bottom) / (prps.fontSize * 1.2f); float Start = (this->rcAxis.bottom - this->transformation.ty) / this->transformation.sy; float End = (this->rcAxis.top - this->transformation.ty) / this->transformation.sy; float Step = (End - Start) / maxLabels; //rounding float base = 1.f / Start; float test = Start * base; #if 0 Start = std::floorf(Start * 100.f) / 100.f; End = std::floorf(End * 100.f) / 100.f; Step = std::floorf(Step * 100.f) / 100.f; #endif // 0 //-test for (float i = Start; i < End; i += Step) { std::wstringstream ss; ss << std::fixed << std::setprecision(5) << i; pPlatform->DrawText(makepoint(left, i * transformation.sy + transformation.ty), ss.str().c_str()); } ουσιαστικα κανω invert transform των screen coords ωστε να βρω τι βλεπω σε space coords. Αυτο ομως μου δινει ως πρωτο space coord το 8.177etc. Εγω αυτο θελω να το κανω 8. Θα μου πεις οκ, βαλε ενα floor round whateva, ομως και αυτο δεν κανει επειδη δεν υπαρχουν const. Θα δουλευει στο διαστιμα 8-10 ξερω γω, αλλα δεν θα δουλευει σε 0.8 - 1.0
gon1332 Δημοσ. 17 Μαρτίου 2015 Δημοσ. 17 Μαρτίου 2015 ... Θες να φτιάξεις μία έξυπνη round η οποία αποφασίζει από μόνη της σε ποιό σημείο θα κάνει round; Αυτό θα μπορούσες να το κάνεις με strings και parsing. Διαφορετικά, αν ξέρεις και θες να βάζεις εσύ κάθε φορά σε ποιό δεκαδικό θες στρογγυλοποίηση τότε ρίξε μία ματιά εδώ. Εμένα με έκραξαν για αυτή τη συνάρτηση λόγω περιορισμένης ακρίβειας, αλλά τί να κάνουμε. Αν έχετε να προτείνετε κάτι καλύτερο, καλόδεχούμενο. Πάντως για την περίπτωσή σου δε θα έχεις θέμα. Εδώ θα βρεις και περισσότερα παραδειγματάκια στον κώδικα που σου έδωσα. long double round_f(long double number, int decimal_places) { assert(decimal_places > 0); double power = pow(10, decimal_places-1); number *= power; return (number >= 0) ? ((long long)(number + 0.5))/power : ((long long)(number - 0.5))/power; }
παπι Δημοσ. 17 Μαρτίου 2015 Μέλος Δημοσ. 17 Μαρτίου 2015 Τελικα παραηταν πολυπλοκο TextFormatProperties prps; this->pTextFormat->GetProperties(prps); float maxLabels = (this->rcAxis.top - this->rcAxis.bottom) / (prps.fontSize * 1.2f); float start = (this->rcAxis.bottom - this->transformation.ty) / this->transformation.sy; float end = (this->rcAxis.top - this->transformation.ty) / this->transformation.sy; float step = (end - start) / maxLabels; float magPow = std::powf(10.f, std::floorf(std::log10f(step))); float magMsg = roundf(step / magPow + 0.5); step = magMsg * magPow; start = step * std::ceilf(start / step); end = step * std::floorf(end / step); for (float i = start; i < end; i += step) { std::wstringstream ss; ss << std::fixed << std::setprecision(5) << i; pPlatform->DrawText(makepoint(this->rcLabel.left + this->axisSize, i * transformation.sy + transformation.ty), ss.str().c_str()); }
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα