migf1 Δημοσ. 24 Ιουλίου 2012 Δημοσ. 24 Ιουλίου 2012 Ερώτηση:μερικές φορές,ο μεταγλωττιστής μου βγάζει το εξής σφάλμα(το γράφω περιληπτικά γιατί δεν το θυμάμαι):"scanf is .....Use scanf_s instead").Τι παίζει με το _s(νομίζω ότι ο migf1 έχει ποστάρει παλιότερα κάτι σχετικό); Είναι πιο ασφαλείς παραλλαγές της Microsoft για κάποιες από τις κλασικές συναρτήσεις, πολλές εκ των οποίων υιοθετήθηκαν στην αναθεώρηση C11. Λεπτομέρειες θα βρεις εδώ: http://msdn.microsoft.com/en-us/library/8ef0s5kh%28v=vs.80%29.aspx
capoelo Δημοσ. 26 Ιουλίου 2012 Μέλος Δημοσ. 26 Ιουλίου 2012 Eρώτηση:ο συγκεκριμένος κώδικας αντιγράφει ένα string σε ένα άλλο μέσω επαναλαμβανόμενης κλήσης της συνάρτησης recurse.Το θέμα είναι ότι η printf εκτός απο το string "this is a test",μου εμφανίζει κ κάποια σκουπίδια.Γιατί; > #include<stdio.h> #include<stdlib.h> void rcopy(char *s1,char *s2); int main(void) { char str[80]; rcopy(str,"this is a test"); printf("%s\n",str); system("Pause"); return 0; } void rcopy(char *s1,char *s2) { if(*s2){ *s1++=*s2++; rcopy(s1,s2); } else *s1='/0'; }
migf1 Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 (επεξεργασμένο) Eρώτηση:ο συγκεκριμένος κώδικας αντιγράφει ένα string σε ένα άλλο μέσω επαναλαμβανόμενης κλήσης της συνάρτησης recurse.Το θέμα είναι ότι η printf εκτός απο το string "this is a test",μου εμφανίζει κ κάποια σκουπίδια.Γιατί; > #include<stdio.h> #include<stdlib.h> void rcopy(char *s1,char *s2); int main(void) { char str[80]; rcopy(str,"this is a test"); printf("%s\n",str); system("Pause"); return 0; } void rcopy(char *s1,char *s2) { if(*s2){ *s1++=*s2++; rcopy(s1,s2); } else *s1='/0'; } Εικάζω επειδή στη C δεν υπάρχει χαρακτήρας '/0' οπότε το ... > ... else *s1 = '/0'; ... σίγουρα δεν βάζει τον μηδενικό χαρακτήρα στο τελείωμα του s1. Επίσης, βγάζει και σχετικό warning ο compiler. Επεξ/σία 26 Ιουλίου 2012 από migf1
migf1 Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 Kατηραμένη βιασύνη... Αλήθεια, γιατί με recursion; Δεν εξυπηρετεί σε κάτι στο συγκεκριμένο... ίσα-ίσα που έχει περισσότερα μειονέκτήματα από τον κανονικό, iterative τρόπο.
Star_Light Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 (επεξεργασμένο) Αφου δεν μπορουν ομως να απεικονισουν με ακριβεια τυπους double οι ΗΥ τοτε γιατι τους εκτυπώνουν κανονικα ομως? Μονο στην συγκριση ειναι το προβληματακι μαλλον. > #include <stdio.h> int main (void) { float x = 0.1 ; double y = 0.1; if( x == y ) puts("Hi"); printf(" %d " , x == y); return 0; } ΕΠισης To void σαν παραμετρος στον ορισμο μιας συνάρτησης ειναι προαιρετικο???? Οταν απο κατω παμε να την γραψουμε δηλαδη τι θα κανει κτλπ.... Επεξ/σία 26 Ιουλίου 2012 από Star_Light
ChRis6 Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 (επεξεργασμένο) Υπαρχει προβλημα στη συγκριση , γιατι η αναπαρασταση δεν ειναι δυνατον να ειναι παντα εγγυημενα ιδια. Στο if εχεις εναν double και εναν float. Λογω του overloaded operator '==' μια μεταβλητη απο τις δυο πρεπει να αλλαξει τυπο. Κατα τη μετατροπη, η αναπαρασταση σε 0 και 1 δεν παραμενει ιδια, γι αυτο και δεν εχει νοημα να κανεις συγκριση. Αλλα ακομα και ιδιο τυπο να ειχαν, παλι θα ειχες προβλημα Λιγο χαλια το ειπα....Ελπιζω να καταλαβες τι θελω να πω Επεξ/σία 26 Ιουλίου 2012 από ChRis6
Star_Light Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 Ναι σωστα στην C99 θα γινει απο float σε double ο ενας τυπος αρα και τα 2 double θα ειναι στο τελος. Για την συγκριση στο if ενταξει το εχω πιάσει... αν και δεν έχω γραψει ενα προγραμματακι δικο μου βάζοντας μέσα το delta που οριζεται για την λυση του προβληματος.... μπορει να μην το κανω... βαριεμαι λιγο. Εκτος και αν το συναντησω στο μελλον..... Απλα στην printf πριν εκτυπωθει δεν αναπαρισταται? εκει δεν χανει πχ?
ChRis6 Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 (επεξεργασμένο) Η printf θα βγαλει το αποτελεσμα της συγκρισης( true ή false ) Επεξ/σία 26 Ιουλίου 2012 από ChRis6
Star_Light Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 (επεξεργασμένο) Η printf θα βγαλει το αποτελεσμα της συγκρισης( true ή false ) A οχι. Εννοουσα οταν απλα δηλωνεις μια double... και της εκχωρεις μια τιμη και μετα ζητας απο την printf να στην εκτυπώσει. Μονο αυτο !!! Εκει δεν έχεις απωλεια ακριβειας σαν αυτη που θα εχεις αμα κάνεις την συγκριση που λεμε? Αλλιως το x == y νταξει ή 1 θα δωσει ή 0. Επεξ/σία 26 Ιουλίου 2012 από Star_Light
migf1 Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 (επεξεργασμένο) A οχι. Εννοουσα οταν απλα δηλωνεις μια double... και της εκχωρεις μια τιμη και μετα ζητας απο την printf να στην εκτυπώσει. Μονο αυτο !!! Εκει δεν έχεις απωλεια ακριβειας σαν αυτη που θα εχεις αμα κάνεις την συγκριση που λεμε? Αλλιως το x == y νταξει ή 1 θα δωσει ή 0. Νομίζω δεν έχεις πιάσει τα αίτια του προβλήματος με την ακρίβεια των πραγματικών αριθμών. Στο link που σου υπέδειξα σε προηγούμενο ποστ, στην τεκμηρίωση της prompt_for, υπάρχει ένα link προς ένα εξαιρετικό αγγλικό άρθρο που τα εξηγεί αναλυτικά, μαζί με πρακτικές λύσεις. Επεξ/σία 26 Ιουλίου 2012 από migf1
Star_Light Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 Νομίζω δεν έχεις πιάσει τα αίτια του προβλήματος με την ακρίβεια των πραγματικών αριθμών. Στο link που σου υπέδειξα σε προηγούμενο ποστ, στην τεκμηρίωση της prompt_for, υπάρχει ένα link προς ένα εξαιρετικό αγγλικό άρθρο που τα εξηγεί αναλυτικά, μαζί με πρακτικές λύσεις. Α αυτο εδω θα λες... http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm θα το κοιταξω
imitheos Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 (επεξεργασμένο) Αφου δεν μπορουν ομως να απεικονισουν με ακριβεια τυπους double οι ΗΥ τοτε γιατι τους εκτυπώνουν κανονικα ομως? Μονο στην συγκριση ειναι το προβληματακι μαλλον. Απλα στην printf πριν εκτυπωθει δεν αναπαρισταται? εκει δεν χανει πχ? A οχι. Εννοουσα οταν απλα δηλωνεις μια double... και της εκχωρεις μια τιμη και μετα ζητας απο την printf να στην εκτυπώσει. Μονο αυτο !!! Εκει δεν έχεις απωλεια ακριβειας σαν αυτη που θα εχεις αμα κάνεις την συγκριση που λεμε? Αλλιως το x == y νταξει ή 1 θα δωσει ή 0. Η ακρίβεια είναι μία απλά μπορεί ο αριθμός να είναι τέτοιος ώστε να μην την βλέπεις. Με άλλα λόγια, το printf είναι άτιμο και λέει ψέματα > #include <stdio.h> int main(void) { float f = 0.13; printf("default (precision = 6) = %f\n", f); printf("precision = 8 = %.8f\n", f); printf("precision = 10 (tada) = %.10f\n", f); printf("precision = 12 = %.12f\n", f); return 0; } Έξοδος: > % ./a.out default (precision = 6) = 0.130000 precision = 8 = 0.13000000 precision = 10 (tada) = 0.1299999952 precision = 12 = 0.129999995232 [offtopic] Τα code tags δεν έχουν monospace γραμματοσειρά πλέον ? Επίσης μου φάγανε το identation τα άτιμα [/offtopic] Επεξ/σία 26 Ιουλίου 2012 από imitheos
Star_Light Δημοσ. 26 Ιουλίου 2012 Δημοσ. 26 Ιουλίου 2012 (επεξεργασμένο) @imitheos δεν θα το πιστεψεις !!! Ακριβως τωρα εμπαινα να προλάβω τον migf1 για πριν.... γιατι οντως πήγαινε προς τρολαρισμα αυτη τη φορα επειδη εδωσες φραση κλειδι την προηγουμενη φορα (δεν διαβασα το αρθρο που εδωσε το αφησα για αυριο αλλα σαν να μου ηρθε μια καλη ιδεα και τελικα να το βρηκα χωρις να διαβασω ολο αυτο ) Λοιπον ειναι αυτο που μου ελεγες και τις προαλλες οτι πχ ακριβεια σε εναν αριθμο σημαινει άπειρα ψηφια ενω ο χωρος στα PC ειναι πεπερασμενος.... πχ το 0.333333 σημαινει απειρα ψηφια ( η μια ακριβεια που λες και εσυ)... οποτε απο ενα σημειο και μετα θα αρχισει να "ρεταρει" η printf δεν θα το δειξει οπως γραφεις και εσυ επειδη διπλα απο τον μορφοποιητη της εχεις δωσει μια οδηγια για λιγοτερα ψηφια πχ αυτο βεβαια αλλαζει οσο τα μεγαλωνεις .... και σε μια συγκριση θα φανει που ειναι περισσοτερα αυτη ειναι και η διαφορα. Το θεμα ειναι οτι μπηκα να σας προλαβω να το γραψω και βλεπω συμφωνουμε! Κατι σχετικα άσχετο.... οταν λεγαμε για implicit conversions απο τον compiler ο κανονας για float ηταν να προβιβαζεται σε double... αυτο επειδη ο double εχει λογικα μεγαλυτερη ακριβεια απο εναν float. (ΑΠλα μιας και το εφερε η κουβεντα που ξανακοιταξα τους κινητης υποδιαστολης). Επεξ/σία 26 Ιουλίου 2012 από Star_Light
imitheos Δημοσ. 27 Ιουλίου 2012 Δημοσ. 27 Ιουλίου 2012 (επεξεργασμένο) οποτε απο ενα σημειο και μετα θα αρχισει να "ρεταρει" η printf δεν θα το δειξει οπως γραφεις και εσυ επειδη διπλα απο τον μορφοποιητη της εχεις δωσει μια οδηγια για λιγοτερα ψηφια πχ αυτο βεβαια αλλαζει οσο τα μεγαλωνεις .... και σε μια συγκριση θα φανει που ειναι περισσοτερα αυτη ειναι και η διαφορα. Το θεμα ειναι οτι μπηκα να σας προλαβω να το γραψω και βλεπω συμφωνουμε! Για την ακρίβεια δεν ρετάρει η printf απλά δουλεύει όπως της λες να δουλέψει. Στο παράδειγμα που έδωσα πριν, το 0.13 σε 32bit ieee754 float είναι ο αριθμός 0x3E051EB8 δηλαδή σε δυαδικό 00111110 00000101 00011110 10111000 οπότε έχουμε Sign = 0 άρα θετικός, Exponent = 01111100 άρα 124 και Mantissa = 00001010001111010111000 Ο αριθμός που προκύπτει είναι 2124 - 127 * (1 + 2-5 + 2-7 + 2-11 + 2-12 + 2-13 + 2-14 + 2-16 + 2-18 + 2-19 + 2-20) = 0.125 * 1,03999996185 και έτσι ο αριθμός σου είναι ο 0,129999995232. The conversion specifier f, F The double argument is rounded and converted to decimal notation in the style [-]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is explicitly zero, no decimal-point character appears. If a decimal point appears, at least one digit appears before it. Όπως βλέπεις, όταν δίνεις σκέτο %f στην printf της λες να χρησιμοποιήσει ακρίβεια 6 ψηφίων οπότε στρογγυλοποιεί τον αριθμό σε 6 ψηφία και σου εμφανίζει το 0.130000. Ο αριθμός όμως δεν παύει να είναι ο ...232 για αυτό και οι συγκρίσεις αποτυγχάνουν. Επεξ/σία 27 Ιουλίου 2012 από imitheos 1
Προτεινόμενες αναρτήσεις