Domme vraag, waarom werkt deze for loop af en toe!

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • itcouldbeanyone
  • Registratie: Augustus 2014
  • Laatst online: 12-09 21:49
waneer ik als String 5Wi invoer, krijg ik als verwacht 21248
voer ik 1Sq in krijg ik 5631.

dit verschil per waarde, maar kan er maar geen oorzaak achter vinden.
waarom is hij af en toe 1 waarde te laag ?


zie onderstaand

Arduino:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 

uint32_t FromBase62(String value){
  if(value.equals("0")||value.equals("1")||value.equals("2")||value.equals("3")||value.equals("4")||value.equals("5")||value.equals("6")||value.equals("7")||value.equals("9")||value.equals("9")){return value.toInt();}
  char base62[62]  = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                       'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                       'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
                       'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
                     };
  uint32_t result=0;
  uint8_t i=0;
  uint8_t ex=0;
  uint8_t j=0;
 
  do {
    for ( i = value.length() + 1; i > 0; i--) {
      for ( j = 0; j < 62; j++) {
        if (base62[j] == value.charAt(value.length() - i)) {
          ex = i - 1;
          result += (j * pow(62, ex));
        }
      }
    }
  } while (i > 0);
  return result+1;
}
 

Ben niet slim, maar wel dom


Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 07-10 19:27

Matis

Rubber Rocket

Je hebt sws twee keer value.equals(9)
Dat moet natuurlijk één keer 8 worden.

Daarnaast denk ik dat je uint32 te klein is en overflowed.

Als laatste gebruik je zowel in de for loop als in de while variabele i.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • Twieka
  • Registratie: Oktober 2010
  • Laatst online: 01-03 17:06
Misschien wel handig om te vermelden welke programmeertaal dit is... Ik gok maar dat het Java is.

Je gebruikt 3 loops terwijl je er eigenlijk maar 1 nodig hebt.
Om de integer waarde van een karakter kan je bv String.indexOf gebruiken:
https://www.tutorialspoint.com/java/java_string_indexof.htm

of bv. kijken of het karakter een getal is (isDigit() ) of een letter (isLetter) en dan nog onderscheiden of het een hoofdletter of niet is (isUpper) en dan respectievelijk 0, A en a ervanaf trekken, of een dictionary gebruiken waarin je alle tekens definieert A => 10, a =>36 etc.

[ Voor 8% gewijzigd door Twieka op 21-07-2017 20:22 ]


Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
Weet je wel waar je mee bezig bent of doe je maar wat? Waarom de "if(value.equals("0")|| ..."? Waarom de "do .. while"? Waarom de "result+1;"?

Niet getest, maar ik denk dat je probleem komt door de pow die met doubles werkt en niet met integers. Het is dan een afrondingsprobleem als je er weer een integer van maakt (al zouden kleine integers zonder probleem in een double moeten passen). Probeer eens met een eigen gemaakte integer-power-functie.

De rest is misschien omslachtig, maar werkt wel. Heb hier geen c++ en heb daarom de code even zo letterlijk mogelijk omgezet naar javascript:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function fromBase62(value) {
    var base62 = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                   'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                   'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
                   'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 
                   'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 
                   't', 'u', 'v', 'w', 'x', 'y', 'z' ];

    var result = 0;
  
    for (var i = value.length + 1; i > 0; i--) {
        for (var j = 0; j < 62; j++) {
            if (base62[j] == value.charAt(value.length - i)) {
                var ex = i - 1;
                result += (j * Math.pow(62, ex));
            }
        }
    }
  
    return result;
}

function test(value) {
    var result = fromBase62(value)
    document.write(value + ' => ' + result + '<br>');
}

test('5Wi');
test('1Sq');

en daar komt uit:
code:
1
2
5Wi => 21248
1Sq => 5632


edit:
De loopjes zou je ook zo kunnen schrijven:
JavaScript:
11
12
13
14
15
16
17
    for (var i = 0; i < value.length; i++) {
        for (var j = 0; j < 62; j++) {
            if (base62[j] == value.charAt(value.length - i - 1)) {
                result += (j * Math.pow(62, i));
            }
        }
    }

[ Voor 9% gewijzigd door Daos op 21-07-2017 20:34 ]


Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 08-10 16:12
Twieka schreef op vrijdag 21 juli 2017 @ 20:05:
Misschien wel handig om te vermelden welke programmeertaal dit is... Ik gok maar dat het Java is.

Je gebruikt 3 loops terwijl je er eigenlijk maar 1 nodig hebt.
Om de integer waarde van een karakter kan je bv String.indexOf gebruiken:
https://www.tutorialspoint.com/java/java_string_indexof.htm

of bv. kijken of het karakter een getal is (isDigit() ) of een letter (isLetter) en dan nog onderscheiden of het een hoofdletter of niet is (isUpper) en dan respectievelijk 0, A en a ervanaf trekken, of een dictionary gebruiken waarin je alle tekens definieert A => 10, a =>36 etc.
C++:
1
uint32_t FromBase62


Sinds wanneer zit een uint32_t in Java?

Acties:
  • 0 Henk 'm!

  • biomass
  • Registratie: Augustus 2004
  • Laatst online: 00:51
if (base62[j] == value.charAt(value.length() - i))

3-4, array index out of bounds?

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
   class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(FromBase62("567", 10));
            Console.WriteLine(FromBase62("123", 10));
            Console.WriteLine(FromBase62("5Wi"));
            Console.WriteLine(FromBase62("1Sq"));
        }

        private static char[] base62 = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                       'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                       'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
                       'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
                     };

        static UInt32 FromBase62(string value, int radix = 62)
        {
            UInt32 result = 0;
            Byte i = 0;
            Byte ex = 0;
            Byte j = 0;

            Console.WriteLine("FromBase{0}('{1}');", radix, value);

            for (i = (byte)(value.Length); i > 0; i--)
            {
                for (j = 0; j < radix; j++)
                {
                    if (base62[j] == value[value.Length - i])
                    {
                        ex = (byte)((int)(i) - 1);
                        Console.WriteLine("\t j={0} \t ex={1} partialsum = {2}", j, ex, j * (UInt32)Math.Pow(radix, (double)ex));
                        result += j * (UInt32)Math.Pow(radix, (double)ex);
                    }
                }
            }
            return result;
        }
    }


Het zal van je compiler afhangen hoe de += operator het product van de 8-bit j en de pow functie bij je 32-bit result optelt.

Begin bij de basics en kijk of je code werkt in 10-tallig stelsel?

FromBase10('567');
         j=5     ex=2 partialsum = 500
         j=6     ex=1 partialsum = 60
         j=7     ex=0 partialsum = 7
567
FromBase10('123');
         j=1     ex=2 partialsum = 100
         j=2     ex=1 partialsum = 20
         j=3     ex=0 partialsum = 3
123
FromBase62('5Wi');
         j=5     ex=2 partialsum = 19220
         j=32    ex=1 partialsum = 1984
         j=44    ex=0 partialsum = 44
21248
FromBase62('1Sq');
         j=1     ex=2 partialsum = 3844
         j=28    ex=1 partialsum = 1736
         j=52    ex=0 partialsum = 52
5632

Acties:
  • 0 Henk 'm!

  • itcouldbeanyone
  • Registratie: Augustus 2014
  • Laatst online: 12-09 21:49
Het is arduino, aangepaste code van java wat base36 was, daar zat die while loop in,
Toen had ik dat aangepast aan deze base62 , en onder processinng.org ofwel java based , goed aan de praat gekregen.

Voor arduino moest ik het een en ander weer aanpassen,
Maar waneer ik een single integer verwacht zoals 3 , werd dit 4, vandaar de eerste equals regel.

Het apparte vond ik dat het bij sommeige getallen wel werkt, terwijl het bij andere niet doet.

Ik weet de code is wat slordig geworden, ik moet het weer ff op orderen,
Bijv "ex" kan net zo goed i-1 zijn.

De doelstelling van dit waazige stukje code is:
Een seriele communicatie die helaas alleen maar strings accepteert, waar ik zoveel mogelijk 32 bit en 4 bit integers over moet versturen.

Het kromme is dat het onder java wel werkte.
In ieder geval bedankt voor alle reacties , dit helpt me zeker op weg :)

Edit, wat me opvalt is dat string.length() onder java een andere waarde heeft dan onder Arduino

[ Voor 5% gewijzigd door itcouldbeanyone op 21-07-2017 23:20 ]

Ben niet slim, maar wel dom


Acties:
  • 0 Henk 'm!

  • itcouldbeanyone
  • Registratie: Augustus 2014
  • Laatst online: 12-09 21:49
Matis schreef op vrijdag 21 juli 2017 @ 17:42:
Je hebt sws twee keer value.equals(9)
Dat moet natuurlijk één keer 8 worden.

Daarnaast denk ik dat je uint32 te klein is en overflowed.

Als laatste gebruik je zowel in de for loop als in de while variabele i.
Lol, 2x 9 je hebt gelijk, voel ik me nu dom,
Maar zonder dat stukje opsomming van equals kreeg ik als ik 3 als waarde verwachte een 4 bijv.

Ben niet slim, maar wel dom


Acties:
  • 0 Henk 'm!

  • Daos
  • Registratie: Oktober 2004
  • Niet online
itcouldbeanyone schreef op vrijdag 21 juli 2017 @ 23:18:
Maar zonder dat stukje opsomming van equals kreeg ik als ik 3 als waarde verwachte een 4 bijv.
Dat komt misschien door die result+1 die je op het eind hebt die daar niet hoort. Als iets niet werkt zoals je verwacht moet je niet lukraak maar meer code toevoegen.

Had je al een eigen integer-power geprobeerd? (proberen is niet hetzelfde als lukraak toevoegen O-) Eigenlijk moet je eerst kijken of de pow die je nu hebt wel de verwachte waarde teruggeeft als je het resultaat daarvan in een integer variabele stopt) Integer-power kan volgens mij zo (niet getest):
C++:
1
2
3
4
5
6
7
8
9
uint32_t ipow(uint32_t base, uint8_t exp) {
    uint32_t result = 1;

    for (uint8_t i = 0; i < exp; i++) {
        result *= base;
    }
    
    return result;
}

Acties:
  • 0 Henk 'm!

  • itcouldbeanyone
  • Registratie: Augustus 2014
  • Laatst online: 12-09 21:49
Daos schreef op vrijdag 21 juli 2017 @ 23:47:
[...]


Dat komt misschien door die result+1 die je op het eind hebt die daar niet hoort. Als iets niet werkt zoals je verwacht moet je niet lukraak maar meer code toevoegen.

Had je al een eigen integer-power geprobeerd? (proberen is niet hetzelfde als lukraak toevoegen O-) Eigenlijk moet je eerst kijken of de pow die je nu hebt wel de verwachte waarde teruggeeft als je het resultaat daarvan in een integer variabele stopt) Integer-power kan volgens mij zo (niet getest):
C++:
1
2
3
4
5
6
7
8
9
uint32_t ipow(uint32_t base, uint8_t exp) {
    uint32_t result = 1;

    for (uint8_t i = 0; i < exp; i++) {
        result *= base;
    }
    
    return result;
}
thankzz die ga ik zeker proberen, ik heb ook me vermoeden dat het aan die pow functie ligt,

Ben niet slim, maar wel dom


Acties:
  • 0 Henk 'm!

  • biomass
  • Registratie: Augustus 2004
  • Laatst online: 00:51
Test je je programma direct op je Arduino of test je het vooraf?

https://arduino.stackexch...thout-having-a-real-board

Acties:
  • 0 Henk 'm!

  • itcouldbeanyone
  • Registratie: Augustus 2014
  • Laatst online: 12-09 21:49
Ik heb de oplossing van Daos gebruikt, het herschrijven van de pow functie geeft wel de juiste resultaten.
dus hartstikke bedankt.

@ biomass, nee ik test het direct op de chip.

Ben niet slim, maar wel dom

Pagina: 1