Skip to main content
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.
Code Golf

Return to Answer

Document testing for deficient / non-deficient
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55

Try it online! Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
9E sahf ; in case input number is 1, let ZF=0 and CF=0
EB 0E jmp cont_loop ; exclude original number as a divisor
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant
 ; (JA) = CF=0 and ZF=0 = deficient
 ; (JNA) = CF=1 or ZF=1 = non-deficient

Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
9E sahf ; in case input number is 1, let ZF=0 and CF=0
EB 0E jmp cont_loop ; exclude original number as a divisor
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant

Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
9E sahf ; in case input number is 1, let ZF=0 and CF=0
EB 0E jmp cont_loop ; exclude original number as a divisor
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant
 ; (JA) = CF=0 and ZF=0 = deficient
 ; (JNA) = CF=1 or ZF=1 = non-deficient
-1 byte by using SAHF
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55

Machine Language (x86 32-bit), 24(削除) 24 (削除ここまで) 23 bytes

It's based on 640KB's abundant numbers answer, with the two additional optimizations from l4m2's answer, where the divisors are subtracted from N instead of added to it (thus simultaneously setting the flags for the return value). An input of 1 is correctly handled, costing 3(削除) 3 (削除ここまで) 2 bytes.

89 C1 89 C3 09 C09E EB 0E 31 D2 50 F7 F1 58 85 D2 75 04 29 CB 72 02 E2 F0

Try it online! Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
099E C0 or sahf eax, eax ; ZF=0, CF=0, ; in case input number is 1, let ZF=0 and CF=0
EB 0E jmp cont_loop ; exclude original number as a divisor
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant

Machine Language (x86 32-bit), 24 bytes

It's based on 640KB's abundant numbers answer, with the two additional optimizations from l4m2's answer, where the divisors are subtracted from N instead of added to it (thus simultaneously setting the flags for the return value). An input of 1 is correctly handled, costing 3 bytes.

89 C1 89 C3 09 C0 EB 0E 31 D2 50 F7 F1 58 85 D2 75 04 29 CB 72 02 E2 F0

Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
09 C0 or eax, eax ; ZF=0, CF=0, in case input number is 1
EB 0E jmp cont_loop ; exclude original number as a divisor
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant

Machine Language (x86 32-bit), (削除) 24 (削除ここまで) 23 bytes

It's based on 640KB's abundant numbers answer, with the two additional optimizations from l4m2's answer, where the divisors are subtracted from N instead of added to it (thus simultaneously setting the flags for the return value). An input of 1 is correctly handled, costing (削除) 3 (削除ここまで) 2 bytes.

89 C1 89 C3 9E EB 0E 31 D2 50 F7 F1 58 85 D2 75 04 29 CB 72 02 E2 F0

Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
9E sahf ; in case input number is 1, let ZF=0 and CF=0
EB 0E jmp cont_loop ; exclude original number as a divisor
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant
Pare it back down to just 1 version, which doesn't have a any overflow problem
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55

Machine Language (x86 32-bit), 2324 bytes

This is a macro that takes an unsigned integer in EAX as input (N), and outputs the result in the Zero Flag (set=perfect, clear=imperfect). It also outputs a result in the Carry Flag (set=abundant, clear=non-abundant). As such, it's actually an answer for both this question and An abundance of integers! , requiring no modification.

It's based on 640KB's abundant numbers answer . I could not use one of, with the two additional optimizations infrom l4m2's answer, where the divisors are subtracted from N instead of added to it (thus simultaneously setting the flags for the return value), because this would break the handling of an input of 1 – that question doesn't explicitly state that handling 1 is needed, but this one does. This cost 4 bytes, but I save 2 bytes by not doing overflow checking. As such, numbers whose aliquot sum exceeds 32 bits will give an incorrect result.

89 C1 31 DB 49 74 0E 31 D2 50 F7 F1 58 85 D2 75 02 01 CB E2 F2 39 D8

Try it online!

Unassembled:

89 C1 mov ecx, eax ; copy input number into ECX
31 DB xor ebx, ebx ; clear EBX (running sum of divisors)
49 dec ecx ; exclude original number as a divisor
74 0E jz short skip_one ; skip loop if original number was 1
 fact_loop:
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 02 jnz short cont_loop ; if not, continue loop
01 CB add ebx, ecx ; add number to sum
 cont_loop:
E2 F2 loop fact_loop
 skip_one:
39 D8 cmp eax, ebx ; compare sum to original number
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant

Machine Language (x86 32-bit), 27 bytes

This version is fully safe against overflows, runs faster (due to exiting the loop the moment the sum of divisors exceeds the input number, as in l4m2's abundant numbers answer ), and still handles anAn input of 1 is correctly handled, as well as indicating both perfection and abundancecosting 3 bytes.

89 C1 89 C3 49 75 04 09 DBC0 EB 100E 31 D2 50 F7 F1 58 85 D2 75 04 29 CB 72 02 E2 F0

Try it online! Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
49 dec ecx ; exclude original number as a divisor
75 04 jnz fact_loop ; skip loop if original number was 1
09 DBC0 or ebxeax, ebxeax ; ZF=0;ZF=0, CF=0;CF=0, indicatein 1case isinput imperfectnumber andis non-abundant1
EB 100E jmp donecont_loop ; exclude original number as a divisor
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant

Machine Language (x86 32-bit), 23 bytes

This is a macro that takes an unsigned integer in EAX as input (N), and outputs the result in the Zero Flag (set=perfect, clear=imperfect). It also outputs a result in the Carry Flag (set=abundant, clear=non-abundant). As such, it's actually an answer for both this question and An abundance of integers!.

It's based on 640KB's abundant numbers answer . I could not use one of the additional optimizations in l4m2's answer, where the divisors are subtracted from N instead of added to it (thus simultaneously setting the flags for the return value), because this would break the handling of an input of 1 – that question doesn't explicitly state that handling 1 is needed, but this one does. This cost 4 bytes, but I save 2 bytes by not doing overflow checking. As such, numbers whose aliquot sum exceeds 32 bits will give an incorrect result.

89 C1 31 DB 49 74 0E 31 D2 50 F7 F1 58 85 D2 75 02 01 CB E2 F2 39 D8

Try it online!

Unassembled:

89 C1 mov ecx, eax ; copy input number into ECX
31 DB xor ebx, ebx ; clear EBX (running sum of divisors)
49 dec ecx ; exclude original number as a divisor
74 0E jz short skip_one ; skip loop if original number was 1
 fact_loop:
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 02 jnz short cont_loop ; if not, continue loop
01 CB add ebx, ecx ; add number to sum
 cont_loop:
E2 F2 loop fact_loop
 skip_one:
39 D8 cmp eax, ebx ; compare sum to original number
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant

Machine Language (x86 32-bit), 27 bytes

This version is fully safe against overflows, runs faster (due to exiting the loop the moment the sum of divisors exceeds the input number, as in l4m2's abundant numbers answer ), and still handles an input of 1 correctly, as well as indicating both perfection and abundance.

89 C1 89 C3 49 75 04 09 DB EB 10 31 D2 50 F7 F1 58 85 D2 75 04 29 CB 72 02 E2 F0

Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
49 dec ecx ; exclude original number as a divisor
75 04 jnz fact_loop ; skip loop if original number was 1
09 DB or ebx, ebx ; ZF=0; CF=0; indicate 1 is imperfect and non-abundant
EB 10 jmp done 
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant

Machine Language (x86 32-bit), 24 bytes

This is a macro that takes an unsigned integer in EAX as input (N), and outputs the result in the Zero Flag (set=perfect, clear=imperfect). It also outputs a result in the Carry Flag (set=abundant, clear=non-abundant). As such, it's actually an answer for both this question and An abundance of integers! , requiring no modification.

It's based on 640KB's abundant numbers answer , with the two additional optimizations from l4m2's answer, where the divisors are subtracted from N instead of added to it (thus simultaneously setting the flags for the return value). An input of 1 is correctly handled, costing 3 bytes.

89 C1 89 C3 09 C0 EB 0E 31 D2 50 F7 F1 58 85 D2 75 04 29 CB 72 02 E2 F0

Try it online!

89 C1 mov ecx, eax ; copy input number into ECX
89 C3 mov ebx, eax ; copy input number into EBX
09 C0 or eax, eax ; ZF=0, CF=0, in case input number is 1
EB 0E jmp cont_loop ; exclude original number as a divisor
 fact_loop: 
31 D2 xor edx, edx ; clear EDX (high word for dividend)
50 push eax ; save original dividend
F7 F1 div ecx ; divide EDX:EAX / ECX
58 pop eax ; restore dividend
85 D2 test edx, edx ; if remainder = 0, it divides evenly
75 04 jnz cont_loop ; if not, continue loop
29 CB sub ebx, ecx ; Subtract divisor from EBX; this simultaneously
 ; changes the running total, and sets the flags for
 ; the return value.
72 02 jc done ; If CF=1, the sum of divisors subtracted from EBX has
 ; exceeded our input number, meaning it is abundant,
 ; and we need to exit the loop now to return this
 ; result in the flags.
 cont_loop: 
E2 F0 loop fact_loop 
 done: ; return value:
 ; (JZ) = ZF=1 = perfect
 ; (JNZ) = ZF=0 = imperfect
 ; (JC) = CF=1 = abundant
 ; (JNC) = CF=0 = non-abundant
Include a fully correct version at 27 bytes
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55
Loading
Flesh out the explanation
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55
Loading
Remove trailing space from machine language hex dump output in TIO
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55
Loading
Switch from nasm to fasm for the TIO, so it can actually be 32-bit
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55
Loading
Add hex dump of machine code to TIO
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55
Loading
added 60 characters in body
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55
Loading
added 2 characters in body
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55
Loading
Source Link
Deadcode
  • 12.9k
  • 2
  • 71
  • 55
Loading

AltStyle によって変換されたページ (->オリジナル) /