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

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

Δημοσ.

Πιθανώς ναι αλλά πως έγραψες τα δεδομένα ? Αν είσαι σε *nix μπορεί να είναι και η αλλαγή γραμμής (0x0a σε *nix). Δες το αρχείο σε ένα hex editor και θα δεις τι είναι :)

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

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

Δημοσ.

Άνοιξε το αρχείο με ένα hex-editor και δες μην έχει κάνα CR η LF στο τέλος.

Στα αρχεία το '\0' είναι κανονικό byte όπως όλα τ'άλλα.

Δημοσ.

Καλησπέρα παιδιά,

 

το παραπάνω προέκυψε όταν θέλησα να χρησιμοποιήσω την σταθερά SIZE_MAX σε C89/90 context, και προφανώς δεν υπήρχε διαθέσιμη.

 

Το quick & dirty...

 

>
#ifndef SIZE_MAX
 #define SIZE_MAX  ( (size_t)-1 )
#endif

 

ήταν η προφανής λύση που μου ήρθε άμεσα, αλλά θέλησα να το διασταυρώσω. Διάβασα πως θεωρείται undefined behavior να κάνεις cast σε unsigned έναν αρνητικό αριθμό (η 1η περίπτωση δηλαδή)... ξέρει κανείς αν ισχύει για να μην ψάχνω στα πρότυπα;

 

Επίσης, ψάχνοντας αν υπάρχει χειροκίνητος τρόπος για x-platform υλοποίηση του TYPE_MAX (όπου TYPE οποιοσδήποτε ακέραιος τύπος) έπεσα σε αυτό το link:

 

http://www.fefe.de/intof.html (ενότητα Finding the minimum and maximum values for a given integer type, αλλά είναι ωραίο όλο το άρθρο).

 

Και πάλι δουλεύει μονάχα με 2's ή 1's complement υλοποιήσεις αρνητικών, αλλά μου έκανε εντύπωση όλη η διαδικασία που ακολουθεί με μια σειρά από macros, για να καταλήξει τελικά σε ένα συμπέρασμα που και πάλι υποφέρει από μη συμβατότητα όταν υπάρχουν padding-bits στον char (όπως είπε και ο imitheos).

 

Οπότε, να υποθέσω πως portable και χειροκίνητα είναι τελικά out of the question, ναι;

 

 

Δημοσ.

>
#ifndef SIZE_MAX
 #define SIZE_MAX  ( (size_t)-1 )
#endif

 

ήταν η προφανής λύση που μου ήρθε άμεσα, αλλά θέλησα να το διασταυρώσω. Διάβασα πως θεωρείται undefined behavior να κάνεις cast σε unsigned έναν αρνητικό αριθμό (η 1η περίπτωση δηλαδή)... ξέρει κανείς αν ισχύει για να μην ψάχνω στα πρότυπα;

 

Που το διάβασες αυτό ? Δες τι έγραψα στο προηγούμενο μήνυμα. Όχι μόνο δεν είναι undefined αλλά είναι ο μόνος portable τρόπος που θα παίξει 100% σε όλες τις περιπτώσεις.

Δημοσ.

είναι σε ubuntu...

ο Bless μου εμφάνισε αυτό: http://i.imgur.com/tYmqH.png

 

Ο χαρακτήρας LineFeed (10 ή 0x0A σε ASCII) δηλώνει την αλλαγή γραμμής και ο χαρακτήρας CarriageReturn (13 ή 0x0D σε ASCII) δηλώνει την επιστροφή του δρομέα στην αρχή. Όταν γράφεις κάτι και αλλάζεις γραμμή, ανάλογα το σύστημα μπαίνει και ο αντίστοιχος χαρακτήρας. Σε *nix μπαίνει ο LF δηλαδή το 0A, σε mac μπαίνει ο CR και σε Windows μπαίνει και CR και LF.

 

Edit: Δείξε μας τον κώδικα να σου πούμε γιατί βγάζει "3 chars written".

Δημοσ.

 

 

Που το διάβασες αυτό ? Δες τι έγραψα στο προηγούμενο μήνυμα. Όχι μόνο δεν είναι undefined αλλά είναι ο μόνος portable τρόπος που θα παίξει 100% σε όλες τις περιπτώσεις.

 

Έτσι ήξερα κι εγώ, αλλά τελικά μπερδεύτηκα (το παθαίνω συχνά όταν διαβάζω τόνους άρθρων :P). Δεν θυμάμαι που το διάβασα γιατί ήταν χτες, αλλά τελικά δουλεύει ακόμα και για μη 2's/1's complement representation των αρνητικών;

 

EDIT

Αν ναι, πως μπορούμε να το κάνουμε generalize για οποιονδήποτε integral τύπο (είτε signed είτε unsigned)?

 

Π.χ...

>
#define INT_MAX        ( ((unsigned int)-1) >> 1 )    // ( ((unsigned int)-1) / 2 )
#define INT_MIN        ( -INT_MAX-1 )

 

παίζει παντού και πάντα;

Δημοσ.

Έτσι ήξερα κι εγώ, αλλά τελικά μπερδεύτηκα (το παθαίνω συχνά όταν διαβάζω τόνους άρθρων :P). Δεν θυμάμαι που το διάβασα γιατί ήταν χτες, αλλά τελικά δουλεύει ακόμα και για μη 2's/1's complement representation των αρνητικών;

 

Έτσι είναι όντως αλλά να σημειώσουμε ότι στην C τα πάντα δουλεύουν με τιμές και όχι με bits. Όταν θέτουμε την τιμή -1 στον unsigned int δεν λέει ο compiler "το -1 έχει όλα τα bit 1 οπότε θα γράψω όλα τα bit 1". Αν γινόταν αυτό θα είχαμε σωστό αποτέλεσμα μόνο σε μηχανές με συμπλήρωμα ως προς 2 που το -1 έχει όντως όλα τα bit 1. Αντίθετα δουλεύει με την τιμή -1.

 

Σε unsigned τύπους δεν γίνεται να υπάρξει overflow (ή αν θέλεις με άλλα λόγια είναι πλήρως ορισμένο τι γίνεται όταν υπάρξει) και έτσι όταν θέτουμε μια αρνητική τιμή έχουμε modulo αριθμητική με (μέγιστη τιμή + 1) μέχρι να βρούμε τιμή που υποστηρίζει ο τύπος. Έτσι το -1 θα γίνει (UINT_MAX + 1) -1 δηλαδή UINT_MAX. Ακόμη και αν το -1 αναπαρίσταται ως 100.......001 (sign+magnitude), θέτοντας -1 σε unsigned τύπο πάντα θα μας δώσει την μέγιστη τιμή που υποστηρίζει ο τύπος για αυτό και είναι ο καλύτερος και πιο portable τρόπος για αυτό.

 

Δουλεύεις μόνο με την τιμή -1. Δεν σε νοιάζει σε τι bit pattern αντιστοιχεί το -1.

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

 

Δουλεύεις μόνο με την τιμή -1. Δεν σε νοιάζει σε τι bit pattern αντιστοιχεί το -1.

 

Ok, thanks! Δεν το πήρα χαμπάρι εκείνο το post σου μέσα στον χαμό, οπότε όλα τζάμι... δουλεύουν κανονικά λοιπόν παντού.

 

>
#define TUINT_MAX(type)    ( (type)-1 )  // δουλεύει παντού
#define TINT_MAX(type)    ( ((unsigned type)-1) >> 1 )  // μόνο για συμπλήρωμα 2
#define TINT_MIN(type)    ( -TINT_MAX(type)-1 )    //   // μόνο για συμπλήρωμα 2

 

Thanks again!

 

EDIT

 

Διόρθωσα κάτι typos στα παραπάνω macros (τα έκανα compile αυτή τη φορά). Σε περίπτωση που αναρωτιέται κανείς, καλούνται κάπως έτσι...

 

>
...
printf( "%zu\n", TUINT_MAX(size_t) );
printf( "%lld %lld\n", TINT_MAX(long long int), TINT_MIN(long long int) );
...

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

Π.χ...

>
#define INT_MAX        ( ((unsigned int)-1) >> 1 )    // ( ((unsigned int)-1) / 2 )
#define INT_MIN        ( -INT_MAX-1 )

 

παίζει παντού και πάντα;

 

 

Ok, thanks! Δεν το πήρα χαμπάρι εκείνο το post σου μέσα στον χαμό, οπότε όλα τζάμι... δουλεύουν κανονικά λοιπόν παντού.

 

>
#define TUINT_MAX(type)    ( (type)-1) )
#define TINT_MAX(type)    ( ((unsigned type)-1) >> 1 )
#define TINT_MIN(type)    ( -TINT_MAX-1 )

 

Thanks again.

 

Κάτσε εγώ δεν είπα ότι αυτά παίζουν παντού αλλά μόνο πως το TUINT_MAX είναι εγγυημένο :P Για τα άλλα δεν βάζω το χέρι μου στη φωτιά.

 

Δεν θυμάμαι ακριβώς τι λέει το πρότυπο για τη σχέση signed-unsigned. Θυμάμαι τρία πράγματα. 1) Πρέπει να καταλαμβάνουν τον ίδιο χώρο (χωρίς να κάνουμε λόγο για τις τιμές. μόνο ίδιο χώρο μαζί με padding δηλαδή sizeof s == sizeof u), 2) Η αναπαράσταση του unsigned είναι pure binary notation δηλαδή κάθε bit αντιστοιχεί και σε μία δύναμη του 2, 3) Οι θετικές τιμές ενός signed έχουν ίδια αναπαράσταση δηλαδή και αυτές ακολουθούν pure binary.

 

Δεν θυμάμαι αν εγγυάται πχ ότι ο unsigned υποστηρίζει μέγιστη τιμή 2*signed. Για αυτό δεν μου καθόταν καλά το 1o macro που έκανε >> 1 και / 2. Επίσης σίγουρα δεν σου εγγυάται κανείς ότι το MIN είναι -MAX-1 γιατί αυτό ισχύει μόνο σε συμπλήρωμα ως προς δύο. Στις άλλες αναπαραστάσεις έχουμε και θετικό και αρνητικό μηδέν οπότε οι τιμές είναι συμμετρικές και η MIN τιμή είναι σκέτο -MAX.

Δημοσ.

Ζήσε Μάη μου να φας τριφύλλι δηλαδή. Έκανα edit και το προηγούμενο post, με τα macros.

Υπάρχουν στανταρισμένα pre-defined macros για την αναπαράσταση αρνητικών, ξέρει κανείς;

Δημοσ.

Ζήσε Μάη μου να φας τριφύλλι δηλαδή. Έκανα edit και το προηγούμενο post, με τα macros.

Υπάρχουν στανταρισμένα pre-defined macros για την αναπαράσταση αρνητικών, ξέρει κανείς;

 

Τι εννοείς pre-defined macros ? Εκτός από αυτά του limits.h ?

Ξανακάνε edit και άλλαξε τα :P Στο MAX δεν χρειάζεται επεξήγηση γιατί μιλάμε για θετικές τιμές οπότε δεν υπάρχει έννοια συμπληρώματος και στο MIN βγάλε το "ή 1". Είπαμε πως σε συμπλήρωμα ως προς 1 η τιμή του θα είναι σκέτο -MAX και όχι -MAX-1. (Όπως είπα πριν έχω την εντύπωση το >> 1 δεν ισχύει πάντα αλλά δεν λέω τίποτα γιατί δεν το θυμάμαι καθόλου. Αν είναι κάποιος άλλος σίγουρος θα μας πει).

Δημοσ.

 

 

Τι εννοείς pre-defined macros ? Εκτός από αυτά του limits.h ?

Ναι (για χειροκίνητη portable υλοποίησή τους).

 

Ξανακάνε edit και άλλαξε τα :P Στο MAX δεν χρειάζεται επεξήγηση γιατί μιλάμε για θετικές τιμές οπότε δεν υπάρχει έννοια συμπληρώματος και στο MIN βγάλε το "ή 1". Είπαμε πως σε συμπλήρωμα ως προς 1 η τιμή του θα είναι σκέτο -MAX και όχι -MAX-1. (Όπως είπα πριν έχω την εντύπωση το >> 1 δεν ισχύει πάντα αλλά δεν λέω τίποτα γιατί δεν το θυμάμαι καθόλου. Αν είναι κάποιος άλλος σίγουρος θα μας πει).

 

Done (sorry για τα πολλά edits, αλλά έχω πήξει και δεν έχω καθαρό μυαλό).

 

Δημοσ.

Το κοίταξα και τελικά ήταν πιο εύκολο να το βρω από ότι νόμιζα.

 

6.

For each of the signed integer types, there is a corresponding (but different) unsigned ... that uses the same amount of storage and same alignment.

Αυτό που είπα για τον ίδιο χώρο αλλά δεν θυμήθηκα την alignment.

 

9

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

Η εγγύηση ότι θέτοντας -1 σε unsigned τύπο παίρνεις την μέγιστη τιμή που υποστηρίζει.

 

9

The range of nonnegative values of a signed integer type is a subrange of the corresponding unsigned integer type, and the representation of the same value in each type is the same.

2

For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; signed char shall not have any padding bits. There shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M ≤ N ).

Οι θετικές τιμές ενός signed πρέπει να είναι υποσύνολο αυτών του unsigned αλλά δεν είναι εγγυημένο ότι UMAX >> 1 == SMAX. Μπορούν κάλλιστα να έχουν ίδιο αριθμό value bits (M == N) οπότε και ίση μέγιστη τιμή (για να γίνει αυτό θα πρέπει ο unsigned να έχει 1 περισσότερο padding bit από τον signed).

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

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