mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 10bit int to 16bit int


Autor: sven s. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

anbei mein code schnippsel wie ich das gelöst hab.
jetzt wollt ich mal fragen ob das nicht ein bischen eleganter geht?


  if(result>= (1<<9))
    {
    result-=(1<<9);
    result=(1<<9)-result;
    result=(1<<15)-result;
    result+=(1<<15);
    }

gruß sven

Autor: sven s. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
achso.. ja falls jemand wissel will wofür das ganze und nicht gleich in 
seine kristallkugel gucken möchte ;-)

http://www.atmel.com/atmel/acrobat/doc2466.pdf
 seite 216

gruß sven

Autor: bwisser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
??????
uint16_t adc_wert = adc_register;
oder
uint16_t adc_wert = (uint16_t)adc_register;

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if (result & (1<<9))
    result |= 0xfc00;

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wert im ADC-Register linksbündig ausrichten und direkt als 16-Bit 
Integer weiterverarbeiten (+/-32K statt +/-512).

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso +/-?
Der ADC-Wert ist doch erstmal unsigned.
=>  [0..65535] statt [0..1023]

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht, wenn man Differenzmessung durchführt. Hatte den Eindruck, dass es 
hier darum ging.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm, schwer zu sagen bei der ausführlichen Beschreibung :-)

Autor: Maxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
int16 = (int10 << 6) >> 6 ; Wenn du einen Barrelshifter zur Verfügung 
hast (i.e. ARM) sonst der Test+Or von Stefan (i.e. AVR)

Vorteil des Shiftings: muss nicht angefasst werden  wenn aus int10 ein 
uint10 wird. Und stellt in jedem Fall sicher, dass wirklich nur die 
unteren 10 Bits auch beachtet werden.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maxx schrieb:
> int16 = (int10 << 6) >> 6 ; Wenn du einen Barrelshifter zur Verfügung
> hast (i.e. ARM) sonst der Test+Or von Stefan (i.e. AVR)
>
> Vorteil des Shiftings: muss nicht angefasst werden  wenn aus int10 ein
> uint10 wird. Und stellt in jedem Fall sicher, dass wirklich nur die
> unteren 10 Bits auch beachtet werden.

Ist aber nicht sonderlich portabel, weil >> für negative Werte 
implementation defined ist.

Zudem ist das Ergebnis undefined, falls in int10 schon ein Bit >= 10 
gesetzt sein sollte (signed overflow).

Autor: Simon Budig (nomis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, für unsigned Werte würde ich für die Spreizung ja vorschlagen:

int16 = (int10 << 6) | (int10 >> 4);

Viele Grüße,
        Simon

Autor: Maxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Ist aber nicht sonderlich portabel, weil >> für negative Werte
> implementation defined ist.

Korrekt. Jedoch auf den Systemen, die einen Barrelshifter besitzen wohl 
anzunehmen. Jedenfalls ist mir noch kein ARM/x86 Compiler die mir dazu 
einfallen untergekommen der kein arithmetic shift right durchführt für 
signed.

> Zudem ist das Ergebnis undefined, falls in int10 schon ein Bit >= 10
> gesetzt sein sollte (signed overflow).

Nicht Korrekt: (Auszug aus dem Ansi-C std)
" The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
bits are filled with zeros.  If E1 has an unsigned type, the value of
the result is E1 multiplied by the quantity, 2 raised to the power E2,
reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1
otherwise.  (The constants ULONG_MAX and UINT_MAX are defined in the
header <limits.h> .)

   The result of E1 >> E2 is E1 right-shifted E2 bit positions.  If E1
has an unsigned type or if E1 has a signed type and a nonnegative
value, the value of the result is the integral part of the quotient of
E1 divided by the quantity, 2 raised to the power E2 .  If E1 has a
signed type and a negative value, the resulting value is
implementation-defined."

Die "Herausgeschifteten" Bits gehen also einfach nur verloren.
Intern nutzt gcc-arm z.B. dieses Shifting um signed ordinal conversionen 
durchzuführen.

Autor: Maxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"E1 >> E2 is E1 right-shifted E2"

Alles andere als arithmetic oder zero-filled verletzt diese Bedingung. 
(Da steht ja nicht "E1 << E2 is (E1 + some remains) right shifted E2"
Insbesondere würde der Fall, dass die herausgeshifteten Bits nicht 
"vergessen" werden für ein C Programm bedeuten, dass
int16 = (int10 << 6) ;
someotherval = aOne + aTwo ;
int16 = (int 16 >> 6) ;
int16 = (int10 << 6) ;
int16 = (int 16 >> 6) ;
someotherval16 = aOne + aTwo ;

sich unterschiedlich verhalten. (Also der Übertrag mit geschiftet wird)

PS: ein signed shift left ist immer identisch mit einem unsigned shift 
left. (Das if in der clause bezieht sich auf die multiplikation, die für 
signed/unsigned anders ausfallen würde), daher ist die Beschränkung des 
Linksschiebens formal irrelevant.

Autor: Maxx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
(sorry mein letzter beitrag bezog sich auf den gelöschten), da nicht 
registriert kann ich selbst nicht löschen)

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maxx schrieb:
> Johann L. schrieb:

>> Zudem ist das Ergebnis undefined, falls in int10 schon ein Bit >= 10
>> gesetzt sein sollte (signed overflow).
> Nicht Korrekt: (Auszug aus dem Ansi-C std)
> " The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated
> bits are filled with zeros.  If E1 has an unsigned type, the value of
> the result is E1 multiplied by the quantity, 2 raised to the power E2,
> reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1
> otherwise.  (The constants ULONG_MAX and UINT_MAX are defined in the
> header <limits.h> .)

Hmmm. Zu signed macht das ja keine Aussage... ISO/IEC 9899 liest sich 
so:
The result of E1 << E2 is E1 left-shifted E2 bit positions; 
vacated bits are filled with zeros. If E1 has an unsigned type,
the value of the result is E1 * 2**E2, reduced modulo one more 
than the maximum value representable in the result type. 
If E1 has a signed type and nonnegative value, and E1 * 2**E2 is
representable in the result type, then that is the resulting value;
otherwise, the behavior is undefined.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.