Benutzer:Martin: Unterschied zwischen den Versionen
Aus LaborWiki
Martin (Diskussion | Beiträge) |
Martin (Diskussion | Beiträge) (Eigene Codeausschnitte hinzugefügt) |
||
Zeile 52: | Zeile 52: | ||
l++%3)==2)puts("");j=0;puts("");}}}main(){char *b=sudoku,*r[]={q,c,w,0};p(b); | l++%3)==2)puts("");j=0;puts("");}}}main(){char *b=sudoku,*r[]={q,c,w,0};p(b); | ||
if(t(0,b,r)){puts("solution:");p(b);}else puts("no solition found");return 0;} | if(t(0,b,r)){puts("solution:");p(b);}else puts("no solition found");return 0;} | ||
== Hilfreiche Funktionen == | |||
char* itoa(signed long val) { | |||
/** Die Ausgabe von itoa(i) ist identisch zu | |||
* sprintf(buf, "%d", i); | |||
* für den gesamten signed 32 bit Bereich. Selbst auf dem PC wesentlich schneller. | |||
*/ | |||
static char buf[13]; // vorsicht beim nächsten Aufruf von itoa ist str weg. | |||
char *sBuf = &buf[12]; | |||
unsigned char negative = val < 0; | |||
unsigned long value, valueOld; | |||
*sBuf = 0; | |||
if (negative) | |||
value = (unsigned long) -val; | |||
else | |||
value = (unsigned long) val; | |||
do { | |||
valueOld = value; | |||
value /= 10; // auch div 10 | |||
*--sBuf = '0' + valueAlt - (value * 10); // schneller als % 10 | |||
} while (value); | |||
if (negative) | |||
*--sBuf = '-'; | |||
return sBuf; | |||
} | |||
=== Schnelle Division / 10 mit Hilfe von Multiplikation und Schieben === | |||
// (uint64_t val) 26 bis 11184819 korrekt, (uint32_t val) 19 bis 81920 korrekt | |||
#define BITS 19 | |||
#define MUL (((1L << BITS)/10) + 1) | |||
unsigned long div10(unsigned long val) { | |||
return ((unsigned long) val * MUL) >> BITS; | |||
} | |||
getestet mit: | |||
void main() { | |||
int i; | |||
printf("Multipilkator %d fuer %d Bits\n", MUL, BITS); | |||
for (i = 0; i < 99999999; i++) { | |||
if ((i/10) != div10(i)) { | |||
printf("Error At %d: %d != %d\n", i, i/10, div10(i)); | |||
return; | |||
} | |||
} | |||
} | |||
=== Konfortable Ausgabe === | |||
char *itoaUint32VarLen(uint32_t value, uint8_t fillWith0, uint8_t lenghtInChars) { | |||
static uint8_t sBuf0[12]; // maximum Value -2147483649 = 12 | |||
uint8_t *sBuf = &sBuf0[11], *sBufWerteBegrenzung; | |||
uint32_t valueAlt; // Alte Wert für schneller % 10 Berechnung | |||
*sBuf = 0; | |||
while (value) { | |||
if (!lenghtInChars) { | |||
sBufWerteBegrenzung = sBuf; | |||
while (sBufWerteBegrenzung < &sBuf0[11]) | |||
*sBufWerteBegrenzung++ = '9'; | |||
break; | |||
} | |||
valueAlt = value; | |||
value /= 10; | |||
*--sBuf = '0' + valueAlt - (value * 10); // schneller als *--sBuf = '0' + (valueAlt % 10) | |||
lenghtInChars--; | |||
} | |||
while (sBuf > sBuf0 && lenghtInChars--) // mit Nullen auffüllen | |||
*--sBuf = fillWith0 ? '0' : ' '; | |||
while (*sBuf) | |||
if (!V24PutChar(*sBuf++, usart)) | |||
return; | |||
} | |||
=== Formatierte Augabe === | |||
char *itoaInt16Formated(int16_t value) { | |||
static uint8_t sBuf0[7]; | |||
uint8_t *sBuf = &sBuf0[6]; | |||
uint8_t minus; | |||
uint16_t valueAlt; // Alte Wert für schnellere % 10 Berechnung | |||
uint16_t valueCalc; // muss unsigned weil signed short kann kein 32768 | |||
*sBuf = 0; | |||
if (value < 0) { // Vorzeichen behandeln | |||
minus = '-'; | |||
valueCalc = -value; | |||
} else { | |||
minus = ' '; | |||
valueCalc = value; | |||
} | |||
while (valueCalc) { | |||
valueAlt = valueCalc; | |||
valueCalc = div10(valueCalc); // schneller als valueCalc /= 10; | |||
*--sBuf = '0' + valueAlt - (valueCalc * 10); // schneller als *--sBuf = '0' + (valueAlt % 10) | |||
} | |||
if (value == 0) | |||
*--sBuf = '0'; | |||
*--sBuf = minus; // Minuszeichen vor die höchstwertigste Stelle setzen | |||
while (sBuf > sBuf0) // mit Leerzeichen auffüllen | |||
*--sBuf = ' '; | |||
return sBuf; | |||
} |
Version vom 5. März 2014, 11:03 Uhr
Seit dem ersten Mikrokontollerworkshop (2005) bin ich im Labor aktiv. Zu meinen beliebtesten Projkten zählt der Borg3d sowie der Farb Borg 3d die ich entwickelt, erbaut und programmiert habe.
Meine Interessen liegen in der Programmierung von C und C++ auf Microcontrollern wie den AVR, Soc-lm32, Arm Cortex M3 aber auch auf PC.
Ich setze Mac OSX schon seit etlichen Jahren und helfe gerne bei Fragen zu OSX.
Außerdem spiele ich Bass in einer Band und beschäftige mich in meiner Freizeit auch viel mit Musik.
Man kenn mich auch als madex (oder Martin3D wegen den großen Intresse an Dreidiminsionalität).
Meine Vorträge
- Optimierung durch Ganzzahlarithmetik für Microcontroller
- Lightning-Talk "Multitasking ohne Betriebssytem im Mikrokontroller"
- Farbborgvortrag Labortage 09
- Crashkurs C-Programmierung für 16x16x16 Borg 3D für Felix 3d in Stade
- Grundlagen der 3D-Grafik mit OpenGL
Meine Projekte
- Borg3d
- Farb Borg 3d
- Portierung des Farb Borg 3d auf Cortex M3
- Optisches Stimmgerät Stimmmopped.
Mein Sudoku Solver
#include <stdio.h> #define _ 0 #define S(x) x, #define D(x) x x x #define L(x) D(S(x)) #define R(x) D(D(S(x))) #define E(f,x) f(x)f(x+1)f(x+2) char sudoku[] = { 1, _, _, _, _, 7, _, 9, _, _, 3, _, _, 2, _, _, _, 8, _, _, 9, 6, _, _, 5, _, _, _, _, 5, 3, _, _, 9, _, _, _, 1, _, _, 8, _, _, _, 2, 6, _, _, _, _, 4, _, _, _, 3, _, _, _, _, _, _, 1, _, _, 4, _, _, _, _, _, _, 7, _, _, 7, _, _, _, 3, _, _, }; char c[]={E(R,0)E(R,3)E(R,6)},q[]={D(D(E(S,0)E(S,3)E(S,6)))},w[]={D(E(L,0)) D(E(L,3))D(E(L,6))};v(char *b, char *r){int l[]={R(0)0},i=82,f,s;for(;--i;l[s] |=1<<f){f=*b++;s=*r++;if(f&&s<9&&l[s]&(1<<f))return 0;}return 1;}h(char *b,char **r){char *o;while(o=*r++)if(!v(b,o))return 0;return 1;}t(char n,char *b,char **r){char i=1;while(1){if(n>80)return 1;if(!b[n])break;n++;}for(;i<10;i++){ b[n]=i;if(h(b,r))if(t(n+1,b,r))return 1;}b[n]=0;return 0;}p(char*b){char j=0,l= 0,i=82;for(;--i;){printf(" %d",*b++);if((j%3)==2)printf(" ");if(++j==9){if(( l++%3)==2)puts("");j=0;puts("");}}}main(){char *b=sudoku,*r[]={q,c,w,0};p(b); if(t(0,b,r)){puts("solution:");p(b);}else puts("no solition found");return 0;}
Hilfreiche Funktionen
char* itoa(signed long val) { /** Die Ausgabe von itoa(i) ist identisch zu * sprintf(buf, "%d", i); * für den gesamten signed 32 bit Bereich. Selbst auf dem PC wesentlich schneller. */ static char buf[13]; // vorsicht beim nächsten Aufruf von itoa ist str weg. char *sBuf = &buf[12]; unsigned char negative = val < 0; unsigned long value, valueOld; *sBuf = 0; if (negative) value = (unsigned long) -val; else value = (unsigned long) val; do { valueOld = value; value /= 10; // auch div 10 *--sBuf = '0' + valueAlt - (value * 10); // schneller als % 10 } while (value); if (negative) *--sBuf = '-'; return sBuf; }
Schnelle Division / 10 mit Hilfe von Multiplikation und Schieben
// (uint64_t val) 26 bis 11184819 korrekt, (uint32_t val) 19 bis 81920 korrekt #define BITS 19 #define MUL (((1L << BITS)/10) + 1) unsigned long div10(unsigned long val) { return ((unsigned long) val * MUL) >> BITS; }
getestet mit:
void main() { int i; printf("Multipilkator %d fuer %d Bits\n", MUL, BITS); for (i = 0; i < 99999999; i++) { if ((i/10) != div10(i)) { printf("Error At %d: %d != %d\n", i, i/10, div10(i)); return; } } }
Konfortable Ausgabe
char *itoaUint32VarLen(uint32_t value, uint8_t fillWith0, uint8_t lenghtInChars) { static uint8_t sBuf0[12]; // maximum Value -2147483649 = 12 uint8_t *sBuf = &sBuf0[11], *sBufWerteBegrenzung; uint32_t valueAlt; // Alte Wert für schneller % 10 Berechnung *sBuf = 0; while (value) { if (!lenghtInChars) { sBufWerteBegrenzung = sBuf; while (sBufWerteBegrenzung < &sBuf0[11]) *sBufWerteBegrenzung++ = '9'; break; } valueAlt = value; value /= 10; *--sBuf = '0' + valueAlt - (value * 10); // schneller als *--sBuf = '0' + (valueAlt % 10) lenghtInChars--; } while (sBuf > sBuf0 && lenghtInChars--) // mit Nullen auffüllen *--sBuf = fillWith0 ? '0' : ' '; while (*sBuf) if (!V24PutChar(*sBuf++, usart)) return; }
Formatierte Augabe
char *itoaInt16Formated(int16_t value) { static uint8_t sBuf0[7]; uint8_t *sBuf = &sBuf0[6]; uint8_t minus; uint16_t valueAlt; // Alte Wert für schnellere % 10 Berechnung uint16_t valueCalc; // muss unsigned weil signed short kann kein 32768 *sBuf = 0; if (value < 0) { // Vorzeichen behandeln minus = '-'; valueCalc = -value; } else { minus = ' '; valueCalc = value; } while (valueCalc) { valueAlt = valueCalc; valueCalc = div10(valueCalc); // schneller als valueCalc /= 10; *--sBuf = '0' + valueAlt - (valueCalc * 10); // schneller als *--sBuf = '0' + (valueAlt % 10) } if (value == 0) *--sBuf = '0'; *--sBuf = minus; // Minuszeichen vor die höchstwertigste Stelle setzen while (sBuf > sBuf0) // mit Leerzeichen auffüllen *--sBuf = ' '; return sBuf; }