Does Arduino have limitations with how large the terminal number can be in a for loop?

For some reason my Arduino outputs the incorrect values for num2 and hypotenuse instead of the message "No special Triangle has a side of this length" for numbers that do not make a non-fractional hypotenuse with any number between 1- 65,535. I wrote another program on code blocks in C and ran it on my computer and it worked fine. I know the Arduino can count up to the value 65,535 and store it in an "unsigned int" variable. However, it seems the "break;" statement in my if statement is giving my program trouble. If I don't include the break it takes forever to output a value. It is REQUIRED for my program to check each and every number to see if it a possible side length for the special triangle based on the user input side length.

void setup() {

  Serial.begin(115200);
  Serial.setTimeout(60000);
}

void loop() {

   computeHypotenuse(); // calls function continuously 
  
}

void computeHypotenuse()
{

  unsigned int userInput;
  
  Serial.println("Please enter any number between 1 and 65535: ");
  userInput = Serial.parseInt(); //User input value 
  
  unsigned int num2; //stores number for second leg of special triangle 
  double hypotenuse; //stores hypotenuse value as a double 
  unsigned int wholeNumber;

  
  for( unsigned int i = 1; i <= 65535; i++ ) // checks all numbers between 1 and 65535
  {
    
    hypotenuse = sqrt(sq(userInput)+sq(i)); //calculates the hypotenuse for every number at i 
    wholeNumber = (unsigned int)hypotenuse; //stores hypotenuse as an unsigned int
    
    if((hypotenuse - wholeNumber) == 0) // checks if hypotenuse is a whole number 
    {
      num2 = i; //Stores value at i for 
      break; //breaks out of loop so it doesnt count all the way to 65535
    }
  }

  if((hypotenuse - wholeNumber) != 0) // if result is a fraction or decimal, the triangle not special
  {
    Serial.println("No special Triangle has a side of this length\n");
  }
  else // If difference is zero, output these non fraction values 
  {
    Serial.print("number 1: ");
    Serial.println(userInput);
    Serial.print("number 2: ");
    Serial.println(num2);
    Serial.print("Hypotenuse: ");
    Serial.println(wholeNumber);
    Serial.println();
  }
}

Because the unsigned int variable i can only hold values up to 65535, which is always <= 65535.

You can't compare doubles for equality. the lint'll kill you. Compare within a tolerance band. Don't use == or !=, they'll NEVER match.

This

if((hypotenuse - wholeNumber) == 0)

is not going to work since 0 is an integer and the subtraction is double.

They WILL match... sometimes. They will lull you into a false sense of security, then stab you in the back when you don't expect it.

1 Like

Theyll only match first time thru with fresh interger assignments.

If you are lucky... but I would not even trust that to work always. If you change from, for example, AVR to ARM or ESP, there's no guarantee.

@madmark2150 not having a go at you here. Point is, we all agree, never trust FLOAT/DOUBLE calculations to match exactly.

that's the idea. that's why I put the break there.

it needs to be

if ((hypotenuse - wholeNumber) <= 0.1)

or somesuch. == or != is NOT correct for an end test.

Fixed that a bit for you. Although it may not matter right here…

a7

What is the condition for?

for( unsigned int i = 1; i <= 65535; i++ ) // checks all numbers between 0 and 65536

The comment is missing the 'over and over'.

for(uint16_t i = 0; true; i++)

Would be equivalent but more obvious endless.

The sq() function is not in math.h.
It is made by Arduino and it is in Arduino.h.

#define sq(x) ((x)*(x))

So two unsigned integers multiplied by each other, is that automatically extended to unsigned long ?
The sqrt() function converts it to a float.
That is not clear code.

Can you make everything with float or everything with integers ? Use 32-bit integers to be able to take make square of a 16-bit integer.

ok so my program must meet these conditions

  1. Prompt the user for an integer between 1-65535, i.e. a positive 16-bit integer

  2. Test all possible 16-bit positive integers as the other leg of the right triangle

  3. If the length of the resultant hypotenuse is also an integer, the resulting triangle is known
    as a “perfect” triangle.

  4. The lengths of the three sides of every perfect triangle with the first leg of the specified
    length should be displayed on the console, one set per line

for the other legs? - triangle has three legs
So you need to review 65k * 65K combinations?
Or to be precise, half of that...

No, just test it with the user input. so if the user input "5" as one of the side lengths of the triangle, the program must find a whole number "x" where (5^2 + x^2)^(1/2) results in a hypotenuse that is also a whole number. this number x must be among 1-65535. If it does it will print it out, if not it will print "No special Triangle has a side of this length"

I think you need to calculate with 32-bit variables when you multiply 16-bit variables.
If you take the square of the hypotenuse, then you don't have to check for the floating point squareroot.

// For: https://forum.arduino.cc/t/does-arduino-have-limitations-with-how-large-the-terminal-number-can-be-in-a-for-loop/1030344/
// 
// This is my own implementation.
// I don't check the resulting squareroot, I check the square of c.
//

void setup() 
{
  Serial.begin(115200);
  Serial.println( "a    b    c");
}

void loop() 
{
  for( uint32_t a = 1; a<65535; a++)
  {
    for( uint32_t b = 1; b<65535; b++)
    {
      // temporary calculation
      uint32_t t = (a*a) + (b*b);   // bug ! this will not fit

      // get the integer squareroot
      uint32_t c = sqrt32( t);

      // check if it was a good number
      if( (c*c) == t)
      {
        Serial.print( a);
        Serial.print( ", ");
        Serial.print( b);
        Serial.print( ", ");
        Serial.print( c);
        Serial.println();
      }
    }
  }
}

// Integer squareroot, Newton methode.
// https://en.wikipedia.org/wiki/Integer_square_root
//
// Square root of integer
uint32_t sqrt32( uint32_t s)
{
  uint32_t x0 = s / 2;			// Initial estimate
	                          // Avoid overflow when s is the maximum representable value

  // Sanity check
  if( x0 != 0)
  {
    uint32_t x1 = (x0 + s / x0) / 2;	// Update

    while(x1 < x0)				// This also checks for cycle
    {
      x0 = x1;
      x1 = (x0 + s / x0) / 2;
    }

    return x0;
  }
  else
  {
    return s;
  }
}

Try the sketch in Wokwi:

Now I'm waiting for the first numbers to arrive... :zzz:

[UPDATE]
After 1½ minute: 3,4,5
After 2½ minutes: 4,3,5 (that is the same)
After 3 minutes: 5, 12, 13
After 4 minutes: 6, 8, 10
After 4½ minutes: 7, 24, 25
This is going better than I thought. After 15 minutes it is at number 21, I'm going to stop it.

Have you tried to investigate how often such numbers come across? Let's say how many answers there will be for numbers from 1 to 100?

Good catch and exactly what i had in mind but inwas focuseed on inequality. I almost didn't put the IF on it.

Thanks for the suggestion. I implemented it and it worked!

Here is the output:

a    b    c
3, 4, 5
4, 3, 5
5, 12, 13
6, 8, 10
7, 24, 25
8, 6, 10
8, 15, 17
9, 12, 15
9, 40, 41
10, 24, 26
11, 60, 61
12, 5, 13
12, 9, 15
12, 16, 20
12, 35, 37
13, 84, 85
14, 48, 50
15, 8, 17
15, 20, 25
15, 36, 39
15, 112, 113
16, 12, 20
16, 30, 34
16, 63, 65
17, 144, 145
18, 24, 30
18, 80, 82
19, 180, 181
20, 15, 25
20, 21, 29
20, 48, 52
20, 99, 101
21, 20, 29
21, 28, 35
21, 72, 75
21, 220, 221
22, 120, 122
23, 264, 265
24, 7, 25
24, 10, 26
24, 18, 30
24, 32, 40
24, 45, 51
24, 70, 74
24, 143, 145
25, 60, 65
25, 312, 313
26, 168, 170
27, 36, 45
27, 120, 123
27, 364, 365
28, 21, 35
28, 45, 53
28, 96, 100
28, 195, 197
29, 420, 421
30, 16, 34
30, 40, 50
30, 72, 78
30, 224, 226
31, 480, 481
32, 24, 40
32, 60, 68
32, 126, 130
32, 255, 257
33, 44, 55
33, 56, 65
33, 180, 183
33, 544, 545
34, 288, 290
35, 12, 37
35, 84, 91
35, 120, 125
35, 612, 613
36, 15, 39
36, 27, 45
36, 48, 60
36, 77, 85
36, 105, 111
36, 160, 164
36, 323, 325
37, 684, 685
38, 360, 362
39, 52, 65
39, 80, 89
39, 252, 255
39, 760, 761
40, 9, 41
40, 30, 50
40, 42, 58
40, 75, 85
40, 96, 104
40, 198, 202
40, 399, 401
41, 840, 841
42, 40, 58
42, 56, 70
42, 144, 150
42, 440, 442
43, 924, 925
44, 33, 55
44, 117, 125
44, 240, 244
44, 483, 485
45, 24, 51
45, 28, 53
45, 60, 75
45, 108, 117
45, 200, 205
45, 336, 339
45, 1012, 1013
46, 528, 530
47, 1104, 1105
48, 14, 50
48, 20, 52
48, 36, 60
48, 55, 73
48, 64, 80
48, 90, 102
48, 140, 148
48, 189, 195
48, 286, 290
48, 575, 577
49, 168, 175
49, 1200, 1201
50, 120, 130
50, 624, 626
51, 68, 85
51, 140, 149
51, 432, 435
51, 1300, 1301
52, 39, 65
52, 165, 173
52, 336, 340
52, 675, 677
53, 1404, 1405
54, 72, 90
54, 240, 246
54, 728, 730
55, 48, 73
55, 132, 143
55, 300, 305
55, 1512, 1513
56, 33, 65
56, 42, 70
56, 90, 106
56, 105, 119
56, 192, 200
56, 390, 394
56, 783, 785
57, 76, 95
57, 176, 185
57, 540, 543
57, 1624, 1625
58, 840, 842
59, 1740, 1741
60, 11, 61
60, 25, 65
60, 32, 68
60, 45, 75
60, 63, 87
60, 80, 100
60, 91, 109
60, 144, 156
60, 175, 185
60, 221, 229
60, 297, 303
60, 448, 452
60, 899, 901
61, 1860, 1861
62, 960, 962
63, 16, 65
63, 60, 87
63, 84, 105
63, 216, 225
63, 280, 287
63, 660, 663
63, 1984, 1985
64, 48, 80
64, 120, 136
64, 252, 260
64, 510, 514
64, 1023, 1025
65, 72, 97
65, 156, 169
65, 420, 425
65, 2112, 2113
66, 88, 110
66, 112, 130
66, 360, 366
66, 1088, 1090
67, 2244, 2245
68, 51, 85
68, 285, 293
68, 576, 580
68, 1155, 1157
69, 92, 115
69, 260, 269
69, 792, 795
69, 2380, 2381
70, 24, 74
70, 168, 182
70, 240, 250
70, 1224, 1226
71, 2520, 2521
72, 21, 75
72, 30, 78
72, 54, 90
72, 65, 97
72, 96, 120
72, 135, 153
72, 154, 170
72, 210, 222
72, 320, 328
72, 429, 435
72, 646, 650
72, 1295, 1297
73, 2664, 2665
74, 1368, 1370
75, 40, 85
75, 100, 125
75, 180, 195
75, 308, 317
75, 560, 565
75, 936, 939
75, 2812, 2813
76, 57, 95
76, 357, 365
76, 720, 724
76, 1443, 1445
77, 36, 85
77, 264, 275
77, 420, 427
77, 2964, 2965
78, 104, 130
78, 160, 178
78, 504, 510
78, 1520, 1522
79, 3120, 3121
80, 18, 82
80, 39, 89
80, 60, 100
80, 84, 116
80, 150, 170
80, 192, 208
80, 315, 325
80, 396, 404
80, 798, 802
80, 1599, 1601
81, 108, 135
81, 360, 369
81, 1092, 1095
81, 3280, 3281
82, 1680, 1682
83, 3444, 3445
84, 13, 85
84, 35, 91
84, 63, 105
84, 80, 116
84, 112, 140
84, 135, 159
84, 187, 205
84, 245, 259
84, 288, 300
84, 437, 445
84, 585, 591
84, 880, 884
84, 1763, 1765
85, 132, 157
85, 204, 221
85, 720, 725
85, 3612, 3613
86, 1848, 1850
87, 116, 145
87, 416, 425
87, 1260, 1263
87, 3784, 3785
88, 66, 110
88, 105, 137
88, 165, 187
88, 234, 250
88, 480, 488
88, 966, 970
88, 1935, 1937
89, 3960, 3961
90, 48, 102
90, 56, 106
90, 120, 150
90, 216, 234
90, 400, 410
90, 672, 678
90, 2024, 2026
91, 60, 109
91, 312, 325
91, 588, 595
91, 4140, 4141
92, 69, 115
92, 525, 533
92, 1056, 1060
92, 2115, 2117
93, 124, 155
93, 476, 485
93, 1440, 1443
93, 4324, 4325
94, 2208, 2210
95, 168, 193
95, 228, 247
95, 900, 905
95, 4512, 4513
96, 28, 100
96, 40, 104
96, 72, 120
96, 110, 146
96, 128, 160
96, 180, 204
96, 247, 265
96, 280, 296
96, 378, 390
96, 572, 580
96, 765, 771
96, 1150, 1154
96, 2303, 2305
97, 4704, 4705
98, 336, 350
98, 2400, 2402
99, 20, 101
99, 132, 165
99, 168, 195
99, 440, 451
99, 540, 549
99, 1632, 1635
99, 4900, 4901
100, 75, 125
100, 105, 145
100, 240, 260
100, 495, 505
100, 621, 629
100, 1248, 1252
100, 2499, 2501
101, 5100, 5101
102, 136, 170
102, 280, 298
102, 864, 870
102, 2600, 2602
103, 5304, 5305
104, 78, 130
104, 153, 185
104, 195, 221
104, 330, 346
104, 672, 680
104, 1350, 1354
104, 2703, 2705
105, 36, 111
105, 56, 119
105, 88, 137
105, 100, 145
105, 140, 175
105, 208, 233
105, 252, 273
105, 360, 375
105, 608, 617
105, 784, 791
105, 1100, 1105
105, 1836, 1839
105, 5512, 5513
106, 2808, 2810
107, 5724, 5725
108, 45, 117
108, 81, 135
108, 144, 180
108, 231, 255
108, 315, 333
108, 480, 492
108, 725, 733
108, 969, 975
108, 1456, 1460
108, 2915, 2917
109, 5940, 5941
110, 96, 146
110, 264, 286
110, 600, 610
110, 3024, 3026
111, 148, 185
111, 680, 689
111, 2052, 2055
111, 6160, 6161
112, 15, 113
112, 66, 130
112, 84, 140
112, 180, 212
112, 210, 238
112, 384, 400
112, 441, 455
112, 780, 788
112, 1566, 1570
112, 3135, 3137
113, 6384, 6385
114, 152, 190
114, 352, 370
114, 1080, 1086
114, 3248, 3250
115, 252, 277
115, 276, 299
115, 1320, 1325
115, 6612, 6613
116, 87, 145
116, 837, 845
116, 1680, 1684
116, 3363, 3365
117, 44, 125
117, 156, 195
117, 240, 267
117, 520, 533
117, 756, 765
117, 2280, 2283
117, 6844, 6845
118, 3480, 3482
119, 120, 169
119, 408, 425
119, 1008, 1015
119, 7080, 7081
120, 22, 122
120, 27, 123
120, 35, 125
120, 50, 130
120, 64, 136
120, 90, 150
120, 119, 169
120, 126, 174
120, 160, 200
120, 182, 218
120, 209, 241
120, 225, 255
120, 288, 312
120, 350, 370
120, 391, 409
120, 442, 458
120, 594, 606
120, 715, 725
120, 896, 904
120, 1197, 1203
120, 1798, 1802
120, 3599, 3601
121, 660, 671
121, 7320, 7321
122, 3720, 3722
123, 164, 205
123, 836, 845
123, 2520, 2523
123, 7564, 7565
124, 93, 155
124, 957, 965
124, 1920, 1924
124, 3843, 3845
125, 300, 325
125, 1560, 1565
125, 7812, 7813
126, 32, 130
126, 120, 174
126, 168, 210
126, 432, 450
126, 560, 574
126, 1320, 1326
126, 3968, 3970
127, 8064, 8065
128, 96, 160
128, 240, 272
128, 504, 520
128, 1020, 1028
128, 2046, 2050
128, 4095, 4097
129, 172, 215
129, 920, 929
129, 2772, 2775
129, 8320, 8321
130, 144, 194
130, 312, 338
130, 840, 850
130, 4224, 4226
131, 8580, 8581
132, 55, 143
132, 85, 157
132, 99, 165
132, 176, 220
132, 224, 260
132, 351, 375
132, 385, 407
132, 475, 493
132, 720, 732
132, 1085, 1093
132, 1449, 1455
132, 2176, 2180
132, 4355, 4357
133, 156, 205
133, 456, 475
133, 1260, 1267
133, 8844, 8845
134, 4488, 4490
135, 72, 153
135, 84, 159
135, 180, 225
135, 324, 351
135, 352, 377
135, 600, 615
135, 1008, 1017
135, 1820, 1825
135, 3036, 3039
135, 9112, 9113
136, 102, 170
136, 255, 289
136, 273, 305
136, 570, 586
136, 1152, 1160
136, 2310, 2314
136, 4623, 4625
137, 9384, 9385
138, 184, 230
138, 520, 538
138, 1584, 1590
138, 4760, 4762
139, 9660, 9661
140, 48, 148
140, 51, 149
140, 105, 175
140, 147, 203
140, 171, 221
140, 225, 265
140, 336, 364
140, 480, 500
140, 693, 707
140, 975, 985
140, 1221, 1229
140, 2448, 2452
140, 4899, 4901
141, 188, 235
141, 1100, 1109
141, 3312, 3315
141, 9940, 9941
142, 5040, 5042
143, 24, 145
143, 780, 793
143, 924, 935
143, 10224, 10225
144, 17, 145
144, 42, 150
144, 60, 156
144, 108, 180
144, 130, 194
144, 165, 219
144, 192, 240
144, 270, 306
144, 308, 340
144, 420, 444
144, 567, 585
144, 640, 656
144, 858, 870
144, 1292, 1300
144, 1725, 1731
144, 2590, 2594
144, 5183, 5185
145, 348, 377
145, 408, 433
145, 2100, 2105
145, 10512, 10513
146, 5328, 5330
147, 140, 203
147, 196, 245
147, 504, 525
147, 1196, 1205
147, 1540, 1547
147, 3600, 3603
147, 10804, 10805
148, 111, 185
148, 1365, 1373
148, 2736, 2740
148, 5475, 5477
149, 11100, 11101
150, 80, 170
150, 200, 250
150, 360, 390
150, 616, 634
150, 1120, 1130
150, 1872, 1878
150, 5624, 5626
151, 11400, 11401
152, 114, 190
152, 285, 323
152, 345, 377
152, 714, 730
152, 1440, 1448
152, 2886, 2890
152, 5775, 5777
153, 104, 185
153, 204, 255
153, 420, 447
153, 680, 697
153, 1296, 1305
153, 3900, 3903
153, 11704, 11705
154, 72, 170
154, 528, 550
154, 840, 854
154, 5928, 5930
155, 372, 403
155, 468, 493
155, 2400, 2405
155, 12012, 12013
156, 65, 169
156, 117, 195
156, 133, 205
156, 208, 260
156, 320, 356
156, 455, 481
156, 495, 519
156, 667, 685
156, 1008, 1020
156, 1517, 1525
156, 2025, 2031
156, 3040, 3044
156, 6083, 6085
157, 12324, 12325
158, 6240, 6242
159, 212, 265
159, 1400, 1409
159, 4212, 4215
159, 12640, 12641
160, 36, 164
160, 78, 178
160, 120, 200
160, 168, 232
160, 231, 281
160, 300, 340
160, 384, 416
160, 630, 650
160, 792, 808
160, 1275, 1285
160, 1596, 1604
160, 3198, 3202
160, 6399, 6401
161, 240, 289
161, 552, 575
161, 1848, 1855
161, 12960, 12961
162, 216, 270
162, 720, 738
162, 2184, 2190
162, 6560, 6562
163, 13284, 13285
164, 123, 205
164, 1677, 1685
164, 3360, 3364
164, 6723, 6725
165, 52, 173
165, 88, 187
165, 144, 219
165, 220, 275
165, 280, 325
165, 396, 429
165, 532, 557
165, 900, 915
165, 1232, 1243
165, 1508, 1517
165, 2720, 2725
165, 4536, 4539
165, 13612, 13613
166, 6888, 6890
167, 13944, 13945
168, 26, 170
168, 49, 175
168, 70, 182
168, 95, 193
168, 99, 195
168, 126, 210
168, 160, 232
168, 224, 280
168, 270, 318
168, 315, 357
168, 374, 410
168, 425, 457
168, 490, 518
168, 576, 600
168, 775, 793
168, 874, 890
168, 1001, 1015
168, 1170, 1182
168, 1760, 1768
168, 2349, 2355
168, 3526, 3530
168, 7055, 7057
169, 1092, 1105
169, 14280, 14281
170, 264, 314
170, 408, 442
170, 1440, 1450
170, 7224, 7226
171, 140, 221
171, 228, 285
171, 528, 555
171, 760, 779
171, 1620, 1629
171, 4872, 4875
171, 14620, 14621
172, 129, 215
172, 1845, 1853
172, 3696, 3700
172, 7395, 7397
173, 14964, 14965
174, 232, 290
174, 832, 850
174, 2520, 2526
174, 7568, 7570
175, 60, 185
175, 288, 337
175, 420, 455
175, 600, 625
175, 2184, 2191
175, 3060, 3065
175, 15312, 15313
176, 57, 185
176, 132, 220
176, 210, 274
176, 330, 374
176, 468, 500
176, 693, 715
176, 960, 976
176, 1932, 1940
176, 3870, 3874
176, 7743, 7745
177, 236, 295
177, 1736, 1745
177, 5220, 5223
177, 15664, 15665
178, 7920, 7922
179, 16020, 16021
180, 19, 181
180, 33, 183
180, 75, 195
180, 96, 204
180, 112, 212
180, 135, 225
180, 189, 261
180, 240, 300
180, 273, 327
180, 299, 349
180, 385, 425
180, 432, 468
180, 525, 555
180, 663, 687
180, 800, 820
180, 891, 909
180, 1344, 1356
180, 1615, 1625
180, 2021, 2029
180, 2697, 2703
180, 4048, 4052
180, 8099, 8101
181, 16380, 16381

I have a feeling that it can be 10 times faster :face_with_raised_eyebrow:

if you don't include the break, the loop won't exit when it finds a value matching your criteria and the value that matches will be lost