Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Ερώτηση:μερικές φορές,ο μεταγλωττιστής μου βγάζει το εξής σφάλμα(το γράφω περιληπτικά γιατί δεν το θυμάμαι):"scanf is .....Use scanf_s instead").Τι παίζει με το _s(νομίζω ότι ο migf1 έχει ποστάρει παλιότερα κάτι σχετικό);

Είναι πιο ασφαλείς παραλλαγές της Microsoft για κάποιες από τις κλασικές συναρτήσεις, πολλές εκ των οποίων υιοθετήθηκαν στην αναθεώρηση C11. Λεπτομέρειες θα βρεις εδώ: http://msdn.microsoft.com/en-us/library/8ef0s5kh%28v=vs.80%29.aspx

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

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';
}

Δημοσ. (επεξεργασμένο)

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.

Επεξ/σία από migf1
Δημοσ.

Kατηραμένη βιασύνη...

 

:P

 

Αλήθεια, γιατί με recursion; Δεν εξυπηρετεί σε κάτι στο συγκεκριμένο... ίσα-ίσα που έχει περισσότερα μειονέκτήματα από τον κανονικό, iterative τρόπο.

Δημοσ. (επεξεργασμένο)

Αφου δεν μπορουν ομως να απεικονισουν με ακριβεια τυπους 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 σαν παραμετρος στον ορισμο μιας συνάρτησης ειναι προαιρετικο????

Οταν απο κατω παμε να την γραψουμε δηλαδη τι θα κανει κτλπ....

Επεξ/σία από Star_Light
Δημοσ. (επεξεργασμένο)

Υπαρχει προβλημα στη συγκριση , γιατι η αναπαρασταση δεν ειναι δυνατον να ειναι παντα εγγυημενα ιδια.

Στο if εχεις εναν double και εναν float. Λογω του overloaded operator '==' μια μεταβλητη απο τις δυο πρεπει να αλλαξει τυπο. Κατα τη μετατροπη, η αναπαρασταση σε 0 και 1 δεν παραμενει ιδια, γι αυτο και δεν εχει νοημα να κανεις συγκριση.

 

Αλλα ακομα και ιδιο τυπο να ειχαν, παλι θα ειχες προβλημα

 

Λιγο χαλια το ειπα....Ελπιζω να καταλαβες τι θελω να πω :ph34r:

Επεξ/σία από ChRis6
Δημοσ.

Ναι σωστα στην C99 θα γινει απο float σε double ο ενας τυπος αρα και τα 2 double θα ειναι στο τελος.

 

Για την συγκριση στο if ενταξει το εχω πιάσει... αν και δεν έχω γραψει ενα προγραμματακι δικο μου βάζοντας μέσα το delta που οριζεται για την λυση του προβληματος.... μπορει να μην το κανω... βαριεμαι λιγο. Εκτος και αν το συναντησω στο μελλον.....

 

Απλα στην printf πριν εκτυπωθει δεν αναπαρισταται? εκει δεν χανει πχ?

Δημοσ. (επεξεργασμένο)

Η printf θα βγαλει το αποτελεσμα της συγκρισης( true ή false )

Επεξ/σία από ChRis6
Δημοσ. (επεξεργασμένο)

Η printf θα βγαλει το αποτελεσμα της συγκρισης( true ή false )

 

A οχι. Εννοουσα οταν απλα δηλωνεις μια double... και της εκχωρεις μια τιμη

και μετα ζητας απο την printf να στην εκτυπώσει. Μονο αυτο !!! Εκει δεν έχεις απωλεια ακριβειας σαν αυτη που θα εχεις αμα κάνεις την συγκριση που λεμε? Αλλιως το x == y νταξει ή 1 θα δωσει ή 0. :D

Επεξ/σία από Star_Light
Δημοσ. (επεξεργασμένο)

A οχι. Εννοουσα οταν απλα δηλωνεις μια double... και της εκχωρεις μια τιμη

και μετα ζητας απο την printf να στην εκτυπώσει. Μονο αυτο !!! Εκει δεν έχεις απωλεια ακριβειας σαν αυτη που θα εχεις αμα κάνεις την συγκριση που λεμε? Αλλιως το x == y νταξει ή 1 θα δωσει ή 0. :D

 

Νομίζω δεν έχεις πιάσει τα αίτια του προβλήματος με την ακρίβεια των πραγματικών αριθμών. Στο link που σου υπέδειξα σε προηγούμενο ποστ, στην τεκμηρίωση της prompt_for, υπάρχει ένα link προς ένα εξαιρετικό αγγλικό άρθρο που τα εξηγεί αναλυτικά, μαζί με πρακτικές λύσεις.

Επεξ/σία από migf1
Δημοσ.

Νομίζω δεν έχεις πιάσει τα αίτια του προβλήματος με την ακρίβεια των πραγματικών αριθμών. Στο link που σου υπέδειξα σε προηγούμενο ποστ, στην τεκμηρίωση της prompt_for, υπάρχει ένα link προς ένα εξαιρετικό αγγλικό άρθρο που τα εξηγεί αναλυτικά, μαζί με πρακτικές λύσεις.

 

Α αυτο εδω θα λες... http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

 

θα το κοιταξω :P

Δημοσ. (επεξεργασμένο)

Αφου δεν μπορουν ομως να απεικονισουν με ακριβεια τυπους double οι ΗΥ τοτε

γιατι τους εκτυπώνουν κανονικα ομως? Μονο στην συγκριση ειναι το προβληματακι μαλλον.

Απλα στην printf πριν εκτυπωθει δεν αναπαρισταται? εκει δεν χανει πχ?

A οχι. Εννοουσα οταν απλα δηλωνεις μια double... και της εκχωρεις μια τιμη

και μετα ζητας απο την printf να στην εκτυπώσει. Μονο αυτο !!! Εκει δεν έχεις απωλεια ακριβειας σαν αυτη που θα εχεις αμα κάνεις την συγκριση που λεμε? Αλλιως το x == y νταξει ή 1 θα δωσει ή 0. :D

 

Η ακρίβεια είναι μία απλά μπορεί ο αριθμός να είναι τέτοιος ώστε να μην την βλέπεις. Με άλλα λόγια, το printf είναι άτιμο και λέει ψέματα :P

 

>
#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]

Επεξ/σία από imitheos
Δημοσ. (επεξεργασμένο)

@imitheos δεν θα το πιστεψεις !!! Ακριβως τωρα εμπαινα να προλάβω τον migf1 για πριν.... γιατι οντως πήγαινε προς τρολαρισμα αυτη τη φορα επειδη εδωσες φραση κλειδι την προηγουμενη φορα :P (δεν διαβασα το αρθρο που εδωσε το αφησα για αυριο αλλα σαν να μου ηρθε μια καλη ιδεα και τελικα να το βρηκα χωρις να διαβασω ολο αυτο )

 

Λοιπον ειναι αυτο που μου ελεγες και τις προαλλες οτι πχ ακριβεια σε εναν αριθμο σημαινει άπειρα ψηφια ενω ο χωρος στα PC ειναι πεπερασμενος.... πχ το 0.333333 σημαινει απειρα ψηφια ( η μια ακριβεια που λες και εσυ)... οποτε απο ενα σημειο και μετα θα αρχισει να "ρεταρει" η printf δεν θα το δειξει οπως γραφεις και εσυ επειδη διπλα απο τον μορφοποιητη της εχεις δωσει μια οδηγια για λιγοτερα ψηφια πχ αυτο βεβαια αλλαζει οσο τα μεγαλωνεις .... και σε μια συγκριση θα φανει που ειναι περισσοτερα :P αυτη ειναι και η διαφορα. Το θεμα ειναι οτι μπηκα να σας προλαβω να το γραψω και βλεπω συμφωνουμε!

 

Κατι σχετικα άσχετο.... οταν λεγαμε για implicit conversions απο τον compiler ο κανονας για float ηταν να προβιβαζεται σε double... αυτο επειδη ο double εχει λογικα μεγαλυτερη ακριβεια απο εναν float. (ΑΠλα μιας και το εφερε η κουβεντα που ξανακοιταξα τους κινητης υποδιαστολης).

Επεξ/σία από Star_Light
Δημοσ. (επεξεργασμένο)

οποτε απο ενα σημειο και μετα θα αρχισει να "ρεταρει" η printf δεν θα το δειξει οπως γραφεις και εσυ επειδη διπλα απο τον μορφοποιητη της εχεις δωσει μια οδηγια για λιγοτερα ψηφια πχ αυτο βεβαια αλλαζει οσο τα μεγαλωνεις .... και σε μια συγκριση θα φανει που ειναι περισσοτερα :P αυτη ειναι και η διαφορα. Το θεμα ειναι οτι μπηκα να σας προλαβω να το γραψω και βλεπω συμφωνουμε!

 

Για την ακρίβεια δεν ρετάρει η 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 για αυτό και οι συγκρίσεις αποτυγχάνουν.

Επεξ/σία από imitheos
  • Like 1
Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...