logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Problem z zasiegiem zmiennej typu "unsigned long int&am

Wojtas32127 05 Maj 2010 22:16 1930 9
REKLAMA
  • #1 8040492
    Wojtas32127
    Poziom 10  
    Witam!
    Poniższy program ma za zadanie na wyświetlaczu wyświetlić zmienne typu "unsigned long int" o dwóch różnych wartościach.
    #include <avr\io.h>
    #include <inttypes.h>
    #include <avr\pgmspace.h>
    #include "opoznienie.h"
    #include "lcd.h"
    #include "makra.h"
    #include "wypdef.h"
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    unsigned long int zmienna1 = 32767;
    unsigned long int zmienna2 = 32768;	
    	
    int main (void) 
    
    {
    // Ustawienie portów do sterowania wyświetlaczem
    DDR(LCD_EPORT) |=  1<<LCD_E | 0x0F<<LCD_D4;
    DDR(LCD_RSPORT) |= 1<<LCD_RS;
    
    //Inicjalizacja wyświetlacza
    LCD_INIT();
    LCDCLS();
    LCD_INIT();
    LCDCLS();
    
    LCD_COMMAND(LCD_ON | LCD_ONDISPLAY |LCD_ONCURSOR);
    LCDCLS();
    
    
    LCD_NAPIS("ZM1=");
    LCD_DEC(zmienna1);
    
    LCD_COMMAND(LCD_DDA | 64);
    LCD_NAPIS("ZM2=");
    LCD_DEC(zmienna2);
    
    for(;;)
    {
    }
    return 0;
    }
    


    Na wyświetlaczu otrzymuje następującą informację.
    ZM1=32767
    ZM2= -32768


    Dlaczego przekraczając zakres zmiennej int mam ujemny wynik na wyświetlaczu? Przecież zmiena typu "unsigned long int" ma większy zasięg o niż 32768. W załączniku umieszczam cały program .

    Proszę używać znaczników code!
    Robak
  • REKLAMA
  • Pomocny post
    #2 8040593
    BoskiDialer
    Poziom 34  
    Literał liczbowy jest domyślnie typu int, a więc 32768[0x8000] po zapisaniu jako int na 2 bajtach [int na avr'ach ma 2 bajty] będzie liczbą ujemną, a więc po rozszerzeniu na 4 bajty rozpropaguje się bit znaku [dając 0xFFFF8000]. Jeśli chcesz podać literał liczbowy o innym typie np unsigned long, to napisz: 32768UL (dołączając litery UL do literału).
  • REKLAMA
  • #3 8040745
    Wojtas32127
    Poziom 10  
    Po dodaniu liter do zmienna2:
    unsigned long int zmienna1 = 32767;
    unsigned long int zmienna2 = 32768UL;
    Na wyświetlaczu wynik pozostał dalej ujemny:(
    Próbowałem też zmieniać zmienne na uint32_t, ale żadnego to rezultatu nie przyniosło. Co jeszcze bym mógł zmienić szanowny "BoskiDialerze", aby otrzymać wyższą liczbę niż te 32768?
  • REKLAMA
  • Pomocny post
    #4 8040823
    utak3r
    Poziom 25  
    Ty nie chcesz liczby większej, niż 32768, tylko większej, niż 32767. Jak na razie nadal masz signed int, skoro 32768 powoduje przekręcenie zakresu.

    A co wyświetli, gdy dasz jeszcze większą liczbę?
  • Pomocny post
    #5 8040867
    tadzik85
    Poziom 38  
    a może itoa zamieniłbyś na ULTOA? tak gwoli ścisłości?
  • #6 8040900
    Wojtas32127
    Poziom 10  
    Przy zwiększeniu liczby.
    unsigned long int zmienna2 = 60000UL;
    Na wyświetlaczu otrzymuje -5536
    Mieszczę się przecież w zasięgu zmiennej signed int sięga przecież do 65535. Co jest nie tak bo mi już pomysły się skończyły :(
  • #7 8040909
    tadzik85
    Poziom 38  
    jw. Jak ty chcesz przetwarzać liczbę 32-bitową bez znaku funkcją która operuje na licznie 16-bitowej ze znakiem? Toż to NIEMOŻLIWE.
  • #8 8040982
    Wojtas32127
    Poziom 10  
    tadzik85 - Możesz szerzej to wyjaśnić?
  • REKLAMA
  • Pomocny post
    #9 8040999
    tadzik85
    Poziom 38  
    void LCD_DEC(int var)
    {
    char bufor[7];
    LCD_NAPIS(itoa(var,bufor,10));
    
    }


    Jak byk napisane ITOA zmień na ULTOA i wszystko będzie ok. I zwiększ bufor bo będzie za mały musi być długości 10.

    Dodano po 2 [minuty]:

    I wypadało by zmienić argument funkcji.
  • #10 8041018
    Wojtas32127
    Poziom 10  
    tadzik86 dzięki za trafną podpowiedz :D .
    Temat zamykam.
REKLAMA