WordUp Δημοσ. 10 Μαρτίου 2009 Δημοσ. 10 Μαρτίου 2009 >#include<stdio.h> int main () { float y=500,x=0.33439, p; p=x*y; printf("\n\n...... %f\n\n", p); return 0; } Ακόμη κανείς δεν βρήκε τίποτα γι αυτό το θέμα....?? Τρέχοντας απλά το παραπάνω προγραμματάκι που κάνει έναν πολλαπλασιασμό μου βγάζει αποτέλεσμα 167,195007 ενώ το κανονικό αποτέλεσμα είναι 167,195... Σε εσάς γίνεται έτσι η βγάζει το κανονικό αποτέλεσμα...? Καμιά πρόταση.. καμιά εξήγηση...? Μαν, δοκίμασε να βάλεις double. Afaik, η float μπορεί να δείξει μέχρι 6 δεκαδικά ψηφία, αλλά δεν παίρνω και όρκο.
Ocyrrhoexanthub Δημοσ. 10 Μαρτίου 2009 Δημοσ. 10 Μαρτίου 2009 >#include<stdio.h> int main () { float y=500,x=0.33439, p; p=x*y; printf("\n\n...... %f\n\n", p); return 0; } Ακόμη κανείς δεν βρήκε τίποτα γι αυτό το θέμα....?? Τρέχοντας απλά το παραπάνω προγραμματάκι που κάνει έναν πολλαπλασιασμό μου βγάζει αποτέλεσμα 167,195007 ενώ το κανονικό αποτέλεσμα είναι 167,195... Σε εσάς γίνεται έτσι η βγάζει το κανονικό αποτέλεσμα...? Καμιά πρόταση.. καμιά εξήγηση...? Το πρότυπο C99 καθορίζει ότι εάν δεν υπάρχει διαφορετική οδηγία για το %f, η default τιμή δεκαδικών ψηφίων είναι 6. Το αποτέλεσμα 500·0.33439 δίνει 167.195 τα οποία όμως ο compiler είναι αναγκασμένος λόγω προτύπου και λόγω ορισμού του τύπου του p και του x και του y ως float, να τα γεμίσει έως ότου να συμπληρωθούν 6 δεκαδικά ψηφία. Τα γεμίζει με συγκεκριμένο τρόπο εξ ου και η λάθος τιμή. Ο συγκεκριμένος τρόπος μπορεί να δοθεί εάν μου ζητηθεί. Η χρησιμοποίηση αντί για το %f, του %.3f λύνει το πρόβλημα. Η χρησιμοποίηση double ή long double για τον ορισμό των x,y,p λύνει το πρόβλημα. Μετά.
Directx Δημοσ. 10 Μαρτίου 2009 Δημοσ. 10 Μαρτίου 2009 Να κάνω και εγώ μια ερώτηση ρε παιδιά; Ποστάρω εδώ για να μην ανοίγω άλλο thread άσκοπα, και το ερώτημά μου έχει να κάνει πάλι με floating point calculations. Λοιπόν, έχω γράψει το παρακάτω προγραμματάκι >#include <stdio.h> #include <math.h> float calc(float n1, float n2); int main(void) { float num1, num2, result; printf("Enter two floating point numbers (q to quit): "); while (scanf("%f %f", &num1, &num2) == 2) { result = calc(num1,num2); printf("\nThe result is %f \n", result); printf("Enter two floating point numbers (q to quit): "); result = 0; } return 0; } float calc(float n1, float n2) { return (fabs(n1-n2)/(n1*n2)); //επιστρέφει το πηλίκο της απόλυτης τιμή της διαφοράς των δύο αριθμών με το γινόμενο τους } Γιατί αν δηλώσω τις μεταβλητές ως double αλλά και το return type της συνάρτησης ως double, δίνει άκυρα αποτελέσματα του στυλ: > Enter two floating point numbers (q to quit): 2 1 The result is 11298...565.000000 (μην κάνετε σχόλια γιατί έχω βάλει την πράξη σε function, άσκηση είναι...) Εάν τις κάνω float, no problem :/ Εκτός από την αλλαγή των float σε double άλλαξε και το scanf από %f σε %lf ώστε οι τιμές να γίνονται parse ως double. > #include <stdio.h> #include <math.h> double calc(double n1, double n2); int main(void) { double num1, num2, result; printf("Enter two doubleing point numbers (q to quit): "); while (scanf("%lf %lf", &num1, &num2) == 2) { result = calc(num1,num2); printf("\nThe result is %f \n", result); printf("Enter two doubleing point numbers (q to quit): "); result = 0; } getchar(); return 0; } double calc(double n1, double n2) { return (fabs(n1-n2)/(n1*n2)); //επιστρέφει το πηλίκο της απόλυτης τιμή της διαφοράς των δύο αριθμών με το γινόμενο τους } =============================================================== >#include<stdio.h> int main () { float y=500,x=0.33439, p; p=x*y; printf("\n\n...... %f\n\n", p); return 0; } Ακόμη κανείς δεν βρήκε τίποτα γι αυτό το θέμα....?? Τρέχοντας απλά το παραπάνω προγραμματάκι που κάνει έναν πολλαπλασιασμό μου βγάζει αποτέλεσμα 167,195007 ενώ το κανονικό αποτέλεσμα είναι 167,195... Σε εσάς γίνεται έτσι η βγάζει το κανονικό αποτέλεσμα...? Καμιά πρόταση.. καμιά εξήγηση...? Όπως εξήγησα ήδη στο πρώτο μου post (http://www.insomnia.gr/forum/showpost.php?p=2605371&postcount=11) είναι θέμα της ακρίβειας που ζητάς από την C. Για παράδειγμα δώσε %.3f και θα έχεις την τιμή που επιθυμείς. > #include<stdio.h> int main () { float y=500,x=0.33439, p; p=x*y; printf("\n\n...... %.3f\n\n", p); getchar(); return 0; }
karabouzouk... Δημοσ. 12 Μαρτίου 2009 Μέλος Δημοσ. 12 Μαρτίου 2009 Το πρότυπο C99 καθορίζει ότι εάν δεν υπάρχει διαφορετική οδηγία για το %f, η default τιμή δεκαδικών ψηφίων είναι 6. Το αποτέλεσμα 500·0.33439 δίνει 167.195 τα οποία όμως ο compiler είναι αναγκασμένος λόγω προτύπου και λόγω ορισμού του τύπου του p και του x και του y ως float, να τα γεμίσει έως ότου να συμπληρωθούν 6 δεκαδικά ψηφία. Τα γεμίζει με συγκεκριμένο τρόπο εξ ου και η λάθος τιμή. Ο συγκεκριμένος τρόπος μπορεί να δοθεί εάν μου ζητηθεί. Η χρησιμοποίηση αντί για το %f, του %.3f λύνει το πρόβλημα. Η χρησιμοποίηση double ή long double για τον ορισμό των x,y,p λύνει το πρόβλημα. Μετά. Αν δεν σου κάνει κόπο εξήγησε με τι τρόπο γεμίζει τα δεκαδικά μήπως καταλάβω καλύτερα... Με τι τρόπο γίνεται ο πολλαπλασιασμός δηλαδή....
bxenos Δημοσ. 12 Μαρτίου 2009 Δημοσ. 12 Μαρτίου 2009 @karabouzouk Σωστά σου είπαν για την ακρίβεια, αλλά λάθος να το παίξεις με τα δεκαδικά. Ο λόγος που εμφανίζεται το λάθος είναι γιατί ο foros 0.33439 που βάζεις, αποθηκεύεται σαν 0.3343900144. Κανε άμα θες ένα >printf("%20.15f",(float)foros) για να δεις τι έχει "αποθηκευτεί" μέσα του (το αποθηκευτεί είναι σε εισαγωγικά, διότι είναι define, αλλά πριν την πράξη ή την εκτύπωση ο compiler το αποθηκεύει). Δώσε double σε όλες τις τιμές και κάνε το foros double >const double foros = 0.33439; ή #define foros ((double)0.33439) ή #define foros 0.33439l και τα scanf να γίνουν με %lf αντί %f και θα δουλέψουν όλα ρολόι
Kleanthis Δημοσ. 14 Μαρτίου 2009 Δημοσ. 14 Μαρτίου 2009 Προσπαθώ να κάνω το απλούστατο του απλούστατου - αρχικοποίηση πίνακα: #include <stdio.h> #include <stdlib.h> main() { int j; float pin[28]; for (j=0;j<28;j++); scanf("%f",pin[j]); system ("PAUSE"); } και μόλις βάλω μία τιμή σταματάει.Στο debug μου βγάζει:An access violation ( segmentation fault ) raised in your program. Γνωρίζει κανείς γιατί το κάνει αυτό και πως λύνεται;Ευχαριστώ πολύ!
parsifal Δημοσ. 14 Μαρτίου 2009 Δημοσ. 14 Μαρτίου 2009 for (j=0;j<28;j++) /* Χωρίς ερωτηματικό στο τέλος */ scanf("%f", &pin[j]); Ο κώδικας ολοκληρωμένος: >#include <stdio.h> #include <stdlib.h> int main(void) { int j; float pin[28]; for(j=0;j<28;j++) /* Χωρίς τον χαρακτήρα ';' στο τέλος */ scanf("%f", &pin[j]); /* Πρόσεξε τον χαρακτήρα '&' που προστέθηκε! */ system("PAUSE"); return 0; }
karabouzouk... Δημοσ. 15 Μαρτίου 2009 Μέλος Δημοσ. 15 Μαρτίου 2009 @karabouzouk Σωστά σου είπαν για την ακρίβεια, αλλά λάθος να το παίξεις με τα δεκαδικά. Ο λόγος που εμφανίζεται το λάθος είναι γιατί ο foros 0.33439 που βάζεις, αποθηκεύεται σαν 0.3343900144. Κανε άμα θες ένα >printf("%20.15f",(float)foros) για να δεις τι έχει "αποθηκευτεί" μέσα του (το αποθηκευτεί είναι σε εισαγωγικά, διότι είναι define, αλλά πριν την πράξη ή την εκτύπωση ο compiler το αποθηκεύει). Δώσε double σε όλες τις τιμές και κάνε το foros double >const double foros = 0.33439; ή #define foros ((double)0.33439) ή #define foros 0.33439l και τα scanf να γίνουν με %lf αντί %f και θα δουλέψουν όλα ρολόι Έχεις δίκιο για το double αλλά έχω κάποιες απορίες... πρώτον με τι τρόπο ακριβώς αποθηκεύονται πχ τα define και δεν έχω ακριβώς τον αριθμό που αποθηκεύω..? δεύτερον τι ακριβώς είναι το %lf γιατί δεν το έχω ξαναδεί... τέλος πόσα δεκαδικά και ακέραια ψηφία έχει ο float, double κλπ...? και ελπίζω εξηγώντας μου αυτά να καταλάβω και γιατί χρειάζεται να ορίσω τις μεταβλητές double και δεν δουλεύει και με float.. Ευχαριστώ πολύ για το χρόνο σας..!
Evgenios1 Δημοσ. 15 Μαρτίου 2009 Δημοσ. 15 Μαρτίου 2009 Για τα format δες εδω http://en.wikipedia.org/wiki/Scanf#Format_string_specifications λεει οτι το lf ειναι Scan as a double floating-point number (θα σε γελασω το τι ακριβος ειναι)
bxenos Δημοσ. 16 Μαρτίου 2009 Δημοσ. 16 Μαρτίου 2009 πρώτον με τι τρόπο ακριβώς αποθηκεύονται πχ τα define και δεν έχω ακριβώς τον αριθμό που αποθηκεύω..? δεύτερον τι ακριβώς είναι το %lf γιατί δεν το έχω ξαναδεί... τέλος πόσα δεκαδικά και ακέραια ψηφία έχει ο float, double κλπ...? και ελπίζω εξηγώντας μου αυτά να καταλάβω και γιατί χρειάζεται να ορίσω τις μεταβλητές double και δεν δουλεύει και με float.. Ευχαριστώ πολύ για το χρόνο σας..! τα define δεν αποθηκεύονται, 1000000 define δεν πιάνουν ούτε 1 byte στο exe του προγράμματος σου. %f,%lf χρειάζονται στην scanf για να ξέρει τι μέγεθος mastissa και exponent να ενημερώσει (απλής ή διπλής ακρίβειας αριθμούς). Ούτε με double δουλεύει πάντα. Αυτή είναι οι ιδιαιτερότητα των υπολογιστών, έχουν περιορισμούς στην ακρίβεια. π.χ. μια ερώτηση: το 1/3 πόσα δεκαδικά ψηφεία έχει; Μπορούν να αποθηκευτούν σε float ή double; Έστω ότι καταφέρναμε να αποθηκεύσουμε αριθμούς με άπειρα δεκαδικά ψηφία. Πόσο χρόνο θα θέλαμε για να κάνουμε τις πράξεις τέτοιων αριθμών; Στις σχολές πληροφορικής υπάρχει μάθημα αριθμητικής ανάλυσης γι'αυτο το λόγο.
karabouzouk... Δημοσ. 16 Μαρτίου 2009 Μέλος Δημοσ. 16 Μαρτίου 2009 τα define δεν αποθηκεύονται, 1000000 define δεν πιάνουν ούτε 1 byte στο exe του προγράμματος σου.%f,%lf χρειάζονται στην scanf για να ξέρει τι μέγεθος mastissa και exponent να ενημερώσει (απλής ή διπλής ακρίβειας αριθμούς). Ούτε με double δουλεύει πάντα. Αυτή είναι οι ιδιαιτερότητα των υπολογιστών, έχουν περιορισμούς στην ακρίβεια. π.χ. μια ερώτηση: το 1/3 πόσα δεκαδικά ψηφεία έχει; Μπορούν να αποθηκευτούν σε float ή double; Έστω ότι καταφέρναμε να αποθηκεύσουμε αριθμούς με άπειρα δεκαδικά ψηφία. Πόσο χρόνο θα θέλαμε για να κάνουμε τις πράξεις τέτοιων αριθμών; Στις σχολές πληροφορικής υπάρχει μάθημα αριθμητικής ανάλυσης γι'αυτο το λόγο. Εντάξει ρε συ ξεφεύγεις.....καταννοητό ότι δεν μπορούμε να δουλέψουμε με άπειρα δεκαδικά και δεν υπάρχει λόγος.....στο παράδειγμά μου κάνω έναν απλό πολλαπλασιασμό και βγάζω λάθος αποτέλεσμα... με double ok λύνεται το πρόβλημα.... προβλημά μου είναι να καταλάβω γιατί ενώ βάζω τη μεταβλητή φόρος 0,33439 "αποθηκεύεται" ή τέλος πάντων όταν την κάνω printf εμφανίζεται σαν 0.3343900144 όπως είπες και σύ...
bxenos Δημοσ. 16 Μαρτίου 2009 Δημοσ. 16 Μαρτίου 2009 floating point representation ή καλύτερα εδώ >#include <stdio.h> //ο παρακάτω κώδικας λειτουργεί για sizeof(float)==sizeof(long)==4 //δεν φτιάχτηκε για portability αλλα για παραδειγμα "κωδικοποίησης" float void p(float k){ union { float f; unsigned long l; } x; size_t i; x.f = k; printf("%35.27f\t",k); for(i=0;i<32;i++){ putchar((x.l & 0x80000000lu) ? '1':'0'); x.l <<= 1; } printf("\n"); } int main(void){ p(0.33439); return 0; } 1bit=sign, 8bit=exponent, 23bit=value να ο αριθμός 0.33439 όταν αποθηκευτεί σε float 4 bytes (single presition): 0.334390014410018921000000000 και η δυαδική του αναπαράσταση (τα 32bit) σύμφωνα με το προγραμματάκι που παρέθεσα είναι: 0 01111101 01010110011010100101011 απο τα οποία: 0=sign (θετικός) 01111101=125 (στο δεκαδικό) σημαίνει 125-127 = -2 εκθέτης (με βάση το 2) 01010110011010100101011 η mantissa έχει το κρυφό ψηφείο 1 στην αρχή αρα είναι 101010110011010100101011 Να και τα βάρη των ψηφείων: bit 23 = 1 bit 22 = 0.5 bit 21 = 0.25 bit 20 = 0.125 bit 19 = 0.0625 ... δηλαδή το most significant bit είναι το 1 και καθως πηγαίνουμε προς τα πίσω διαιρούμε με το 2. Αν τα βάλεις σε κανένα excel/scalc θα βρείς τον πλήρη πίνακα > Θέση bit βάρος θέσης bit αριθμού μας βάρος αριθμού μας 23 1,00000000000000000000 1 1,00000000000000000000 22 0,50000000000000000000 0 0,00000000000000000000 21 0,25000000000000000000 1 0,25000000000000000000 20 0,12500000000000000000 0 0,00000000000000000000 19 0,06250000000000000000 1 0,06250000000000000000 18 0,03125000000000000000 0 0,00000000000000000000 17 0,01562500000000000000 1 0,01562500000000000000 16 0,00781250000000000000 1 0,00781250000000000000 15 0,00390625000000000000 0 0,00000000000000000000 14 0,00195312500000000000 0 0,00000000000000000000 13 0,00097656250000000000 1 0,00097656250000000000 12 0,00048828125000000000 1 0,00048828125000000000 11 0,00024414062500000000 0 0,00000000000000000000 10 0,00012207031250000000 1 0,00012207031250000000 9 0,00006103515625000000 0 0,00000000000000000000 8 0,00003051757812500000 1 0,00003051757812500000 7 0,00001525878906250000 0 0,00000000000000000000 6 0,00000762939453125000 0 0,00000000000000000000 5 0,00000381469726562500 1 0,00000381469726562500 4 0,00000190734863281250 0 0,00000000000000000000 3 0,00000095367431640625 1 0,00000095367431640625 2 0,00000047683715820313 0 0,00000000000000000000 1 0,00000023841857910156 1 0,00000023841857910156 0 0,00000011920928955078 1 0,00000011920928955078 Σύνολο 1,33756005764008000000 (μεχρι 20 ψηφία ακρίβεια έχει το oo calc που δοκίμασα) η πρώτη στήλη είναι η θέση του bit, η δεύτερη η σημασία της (βάρος), η τρίτη είναι η τιμή των βιτ του αριθμού σου, η τέταρτη είναι το γινόμενο της 2ής με την 3η. Το άθροισμα είναι 1,3375... και αν το πολλαπλασιασουμε με το 2^-2, δινει 0,33439001441001900000 [voila] αν βάλεις στο excel/scalc τους πίνακες που σου έδωσα και στο bit 0 βάλεις 0 αντί για 1 (που έχει), βρίσκεις την αμέσως μικρότεερη δυνατή τιμή που μπορεί να αποθηκευτεί και είναι η 0,33438998460769700000 δηλαδη μετά το 0,33438998460769700000 υπάρχει το 0,33439001441001900000
bxenos Δημοσ. 18 Μαρτίου 2009 Δημοσ. 18 Μαρτίου 2009 προβλημά μου είναι να καταλάβω γιατί ενώ βάζω τη μεταβλητή φόρος 0,33439 "αποθηκεύεται" ή τέλος πάντων όταν την κάνω printf εμφανίζεται σαν 0.3343900144 όπως είπες και σύ... τελικά το κατάλαβες;
Kleanthis Δημοσ. 12 Απριλίου 2009 Δημοσ. 12 Απριλίου 2009 Απλούστατο θέμα που δε μπορώ να καταλάβω γιατί δε λειτουργεί: max=ar[0]; for (j=1;j<NUMBERS;j++) if (ar[j]>max) max=ar[j]; printf("MAX:%d\n",max); Το γράφω ισοδύναμα: max=ar[0]; for (j=1;j<NUMBERS;j++) total=ar[j]>max?ar[j]:max; printf("MAX:%d\n",total); Δεν έχω τα ίδια αποτελέσματα.Μάλλον δεν είναι και τόσο ισοδύναμες οι μορφές.Κάποια ιδέα παρακαλώ πολύ.
bxenos Δημοσ. 12 Απριλίου 2009 Δημοσ. 12 Απριλίου 2009 Απλούστατο θέμα που δε μπορώ να καταλάβω γιατί δε λειτουργεί: max=ar[0]; for (j=1;j<NUMBERS;j++) if (ar[j]>max) max=ar[j]; printf("MAX:%d\n",max); Το γράφω ισοδύναμα: max=ar[0]; for (j=1;j<NUMBERS;j++) total=ar[j]>max?ar[j]:max; printf("MAX:%d\n",total); Δεν έχω τα ίδια αποτελέσματα.Μάλλον δεν είναι και τόσο ισοδύναμες οι μορφές.Κάποια ιδέα παρακαλώ πολύ. Στην δευτερη περίπτωση αν NUMBERS==0, το total δεν θα πάρει τιμή. Στην δευτερη περίπτωση, το max παραμένει ar[0] (δεν το ενημερωνεις).
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.