Averages/Median: Difference between revisions

(1-based index)
 
(23 intermediate revisions by 16 users not shown)
Line 33:
4.25
</pre>
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
<syntaxhighlight lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program averageMed64.s */
/* use quickselect look pseudo code in wikipedia quickselect */
 
/************************************/
/* Constantes */
/************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessResultValue: .asciz "Result : "
szCarriageReturn: .asciz "\n"
.align 4
TableNumber: .double 4.1, 5.6, 7.2, 1.7, 9.3, 4.4, 3.2
.equ NBELEMENTS, (. - TableNumber) / 8
TableNumber2: .double 4.1, 7.2, 1.7, 9.3, 4.4, 3.2
.equ NBELEMENTS2, (. - TableNumber2) / 8
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
sZoneConv1: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: // entry of program
ldr x0,qAdrTableNumber // address number table
mov x1,#0 // index first item
mov x2,#NBELEMENTS -1 // index last item
bl searchMedian
ldr x0,qAdrTableNumber2 // address number table 2
mov x1,#0 // index first item
mov x2,#NBELEMENTS2 -1 // index last item
bl searchMedian
 
100: // standard end of the program
mov x0, #0 // return code
mov x8, #EXIT // request to exit program
svc #0 // perform the system call
qAdrszCarriageReturn: .quad szCarriageReturn
qAdrTableNumber: .quad TableNumber
qAdrTableNumber2: .quad TableNumber2
qAdrsZoneConv: .quad sZoneConv
qAdrszMessResultValue: .quad szMessResultValue
/***************************************************/
/* search median term in float array */
/***************************************************/
/* x0 contains the address of table */
/* x1 contains index of first item */
/* x2 contains index of last item */
searchMedian:
stp x1,lr,[sp,-16]! // save registers TODO: à revoir génération
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
 
mov x19,x0 // save array address
add x4,x1,x2
add x4,x4,#1 // sum numbers terms
tst x4,#1 // odd ?
bne 1f
lsr x3,x4,#1 // compute median index
bl select // call selection
fmov d0,x0 // save first result
sub x3,x3,#1 // second term
mov x0,x19
bl select // call selection
fmov d1,x0 // save 2ieme résult
fadd d0,d0,d1 // compute average two résults
mov x0,#2
fmov d1,x0
scvtf d1,d1 // conversion integer -> float
fdiv d0,d0,d1
b 2f
1: // even
lsr x3,x4,#1
bl select // call selection
fmov d0,x0
2:
ldr x0,qAdrsZoneConv // conversion float in decimal string
bl convertirFloat
mov x0,#3 // and display result
ldr x1,qAdrszMessResultValue
ldr x2,qAdrsZoneConv
ldr x3,qAdrszCarriageReturn
bl displayStrings
100: // end function
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret
 
/***************************************************/
/* Appel récursif selection */
/***************************************************/
/* x0 contains the address of table */
/* x1 contains index of first item */
/* x2 contains index of last item */
/* x3 contains search index */
select:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
stp x6,x7,[sp,-16]! // save registers
mov x6,x3 // save search index
cmp x1,x2 // first = last ?
bne 1f
ldr x0,[x0,x1,lsl #3] // return value of first index
b 100f // yes -> end
1:
add x3,x1,x2
lsr x3,x3,#1 // compute median pivot
mov x4,x0 // save x0
mov x5,x2 // save x2
bl partition // cutting.quado 2 parts
cmp x6,x0 // pivot is ok ?
bne 2f
ldr x0,[x4,x0,lsl #3] // yes -> return value
b 100f
2:
bgt 3f
sub x2,x0,#1 // index partition - 1
mov x0,x4 // array address
mov x3,x6 // search index
bl select // select lower part
b 100f
3:
add x1,x0,#1 // index begin = index partition + 1
mov x0,x4 // array address
mov x2,x5 // last item
mov x3,x6 // search index
bl select // select higter part
100: // end function
ldp x6,x7,[sp],16 // restaur 2 registers
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/******************************************************************/
/* Partition table elements */
/******************************************************************/
/* x0 contains the address of table */
/* x1 contains index of first item */
/* x2 contains index of last item */
/* x3 contains index of pivot */
partition:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
stp x6,x7,[sp,-16]! // save registers
ldr x4,[x0,x3,lsl #3] // load value of pivot
ldr x5,[x0,x2,lsl #3] // load value last index
str x5,[x0,x3,lsl #3] // swap value of pivot
str x4,[x0,x2,lsl #3] // and value last index
mov x3,x1 // init with first index
1: // begin loop
ldr x6,[x0,x3,lsl #3] // load value
cmp x6,x4 // compare loop value and pivot value
bge 2f
ldr x5,[x0,x1,lsl #3] // if < swap value table
str x6,[x0,x1,lsl #3]
str x5,[x0,x3,lsl #3]
add x1,x1,#1 // and increment index 1
2:
add x3,x3,#1 // increment index 2
cmp x3,x2 // end ?
blt 1b // no loop
ldr x5,[x0,x1,lsl #3] // swap value
str x4,[x0,x1,lsl #3]
str x5,[x0,x2,lsl #3]
mov x0,x1 // return index partition
100:
ldp x6,x7,[sp],16 // restaur 2 registers
ldp x4,x5,[sp],16 // restaur 2 registers
ldp x2,x3,[sp],16 // restaur 2 registers
ldp x1,lr,[sp],16 // restaur 2 registers
ret // return to address lr x30
/***************************************************/
/* display multi strings */
/* new version 24/05/2023 */
/***************************************************/
/* x0 contains number strings address */
/* x1 address string1 */
/* x2 address string2 */
/* x3 address string3 */
/* x4 address string4 */
/* x5 address string5 */
/* x6 address string5 */
/* x7 address string6 */
displayStrings: // INFO: displayStrings
stp x8,lr,[sp,-16]! // save registers
stp x2,fp,[sp,-16]! // save registers
add fp,sp,#32 // save paraméters address (4 registers saved * 8 bytes)
mov x8,x0 // save strings number
cmp x8,#0 // 0 string -> end
ble 100f
mov x0,x1 // string 1
bl affichageMess
cmp x8,#1 // number > 1
ble 100f
mov x0,x2
bl affichageMess
cmp x8,#2
ble 100f
mov x0,x3
bl affichageMess
cmp x8,#3
ble 100f
mov x0,x4
bl affichageMess
cmp x8,#4
ble 100f
mov x0,x5
bl affichageMess
cmp x8,#5
ble 100f
mov x0,x6
bl affichageMess
cmp x8,#6
ble 100f
mov x0,x7
bl affichageMess
100:
ldp x2,fp,[sp],16 // restaur registers
ldp x8,lr,[sp],16 // restaur registers
ret
/******************************************************************/
/* Conversion Float */
/******************************************************************/
/* d0 contains Float */
/* x0 contains address conversion area mini 20 charactèrs */
/* x0 return result length */
/* see https://blog.benoitblanchon.fr/lightweight-float-to-string/ */
convertirFloat:
stp x1,lr,[sp,-16]! // save registres
stp x2,x3,[sp,-16]! // save registres
stp x4,x5,[sp,-16]! // save registres
stp x6,x7,[sp,-16]! // save registres
stp x8,x9,[sp,-16]! // save registres
stp d1,d2,[sp,-16]! // save registres
mov x6,x0 // save area address
fmov x0,d0
mov x8,#0 // result length
mov x3,#'+'
strb w3,[x6] // signe + forcing
mov x2,x0
tbz x2,63,1f
mov x2,1
lsl x2,x2,63
bic x0,x0,x2
mov x3,#'-' // sign -
strb w3,[x6]
1:
adds x8,x8,#1 // next position
cmp x0,#0 // case 0 positive or negative
bne 2f
mov x3,#'0'
strb w3,[x6,x8] // store character 0
adds x8,x8,#1
strb wzr,[x6,x8] // store 0 final
mov x0,x8 // return length
b 100f
2:
ldr x2,iMaskExposant
mov x1,x0
and x1,x1,x2 // exposant
cmp x1,x2
bne 4f
tbz x0,51,3f // test bit 51 to zéro
mov x2,#'N' // case Nan. store byte no possible store integer
strb w2,[x6] // area no aligned
mov x2,#'a'
strb w2,[x6,#1]
mov x2,#'n'
strb w2,[x6,#2]
mov x2,#0 // 0 final
strb w2,[x6,#3]
mov x0,#3
b 100f
3: // case infini positive or négative
mov x2,#'I'
strb w2,[x6,x8]
adds x8,x8,#1
mov x2,#'n'
strb w2,[x6,x8]
adds x8,x8,#1
mov x2,#'f'
strb w2,[x6,x8]
adds x8,x8,#1
mov x2,#0
strb w2,[x6,x8]
mov x0,x8
b 100f
4:
bl normaliserFloat
mov x5,x0 // save exposant
fcvtzu d2,d0
fmov x0,d2 // part integer
scvtf d1,d2 // conversion float
fsub d1,d0,d1 // extraction part fractional
ldr d2,dConst1
fmul d1,d2,d1 // to crop it in full
fcvtzu d1,d1 // convertion integer
fmov x4,d1 // fract value
// conversion part integer to x0
mov x2,x6 // save address begin area
adds x6,x6,x8
mov x1,x6
bl conversion10
add x6,x6,x0
mov x3,#','
strb w3,[x6]
adds x6,x6,#1
mov x0,x4 // conversion part fractionnaire
mov x1,x6
bl conversion10SP
add x6,x6,x0
sub x6,x6,#1
// remove trailing zeros
5:
ldrb w0,[x6]
cmp w0,#'0'
bne 6f
sub x6,x6,#1
b 5b
6:
cmp w0,#','
bne 7f
sub x6,x6,#1
7:
cmp x5,#0 // if exposant = 0 no display
bne 8f
add x6,x6,#1
b 10f
8:
add x6,x6,#1
mov x3,#'E'
strb w3,[x6]
add x6,x6,#1
mov x0,x5 // conversion exposant
mov x3,x0
tbz x3,63,9f // exposant negative ?
neg x0,x0
mov x3,#'-'
strb w3,[x6]
adds x6,x6,#1
9:
mov x1,x6
bl conversion10
add x6,x6,x0
10:
strb wzr,[x6] // store 0 final
adds x6,x6,#1
mov x0,x6
subs x0,x0,x2 // retour de la longueur de la zone
subs x0,x0,#1 // sans le 0 final
 
100:
ldp d1,d2,[sp],16 // restaur registres
ldp x8,x9,[sp],16 // restaur registres
ldp x6,x7,[sp],16 // restaur registres
ldp x4,x5,[sp],16 // restaur registres
ldp x2,x3,[sp],16 // restaur registres
ldp x1,lr,[sp],16 // restaur registres
ret
iMaskExposant: .quad 0x7FF<<52
dConst1: .double 0f1E17
 
/***************************************************/
/* normaliser float */
/***************************************************/
/* x0 contain float value (always positive value and <> Nan) */
/* d0 return new value */
/* x0 return exposant */
normaliserFloat:
stp x1,lr,[sp,-16]! // save registers
fmov d0,x0 // value float
mov x0,#0 // exposant
ldr d1,dConstE7 // no normalisation for value < 1E7
fcmp d0,d1
blo 10f // if d0 < dConstE7
ldr d1,dConstE256
fcmp d0,d1
blo 1f
fdiv d0,d0,d1
adds x0,x0,#256
1:
ldr d1,dConstE128
fcmp d0,d1
blo 1f
fdiv d0,d0,d1
adds x0,x0,#128
1:
ldr d1,dConstE64
fcmp d0,d1
blo 1f
fdiv d0,d0,d1
adds x0,x0,#64
1:
ldr d1,dConstE32
fcmp d0,d1
blo 1f
fdiv d0,d0,d1
adds x0,x0,#32
1:
ldr d1,dConstE16
fcmp d0,d1
blo 2f
fdiv d0,d0,d1
adds x0,x0,#16
2:
ldr d1,dConstE8
fcmp d0,d1
blo 3f
fdiv d0,d0,d1
adds x0,x0,#8
3:
ldr d1,dConstE4
fcmp d0,d1
blo 4f
fdiv d0,d0,d1
adds x0,x0,#4
4:
ldr d1,dConstE2
fcmp d0,d1
blo 5f
fdiv d0,d0,d1
adds x0,x0,#2
5:
ldr d1,dConstE1
fcmp d0,d1
blo 10f
fdiv d0,d0,d1
adds x0,x0,#1
 
10:
ldr d1,dConstME5 // pas de normalisation pour les valeurs > 1E-5
fcmp d0,d1
bhi 100f // fin
ldr d1,dConstME255
fcmp d0,d1
bhi 11f
ldr d1,dConstE256
 
fmul d0,d0,d1
subs x0,x0,#256
11:
ldr d1,dConstME127
fcmp d0,d1
bhi 11f
ldr d1,dConstE128
 
fmul d0,d0,d1
subs x0,x0,#128
11:
ldr d1,dConstME63
fcmp d0,d1
bhi 11f
ldr d1,dConstE64
 
fmul d0,d0,d1
subs x0,x0,#64
11:
ldr d1,dConstME31
fcmp d0,d1
bhi 11f
ldr d1,dConstE32
 
fmul d0,d0,d1
subs x0,x0,#32
11:
ldr d1,dConstME15
fcmp d0,d1
bhi 12f
ldr d1,dConstE16
fmul d0,d0,d1
subs x0,x0,#16
12:
ldr d1,dConstME7
fcmp d0,d1
bhi 13f
ldr d1,dConstE8
fmul d0,d0,d1
subs x0,x0,#8
13:
ldr d1,dConstME3
fcmp d0,d1
bhi 14f
ldr d1,dConstE4
fmul d0,d0,d1
subs x0,x0,#4
14:
ldr d1,dConstME1
fcmp d0,d1
bhi 15f
ldr d1,dConstE2
fmul d0,d0,d1
subs x0,x0,#2
15:
ldr d1,dConstE0
fcmp d0,d1
bhi 100f
ldr d1,dConstE1
fmul d0,d0,d1
subs x0,x0,#1
 
100: // fin standard de la fonction
ldp x1,lr,[sp],16 // restaur registres
ret
.align 2
dConstE7: .double 0f1E7
dConstE256: .double 0f1E256
dConstE128: .double 0f1E128
dConstE64: .double 0f1E64
dConstE32: .double 0f1E32
dConstE16: .double 0f1E16
dConstE8: .double 0f1E8
dConstE4: .double 0f1E4
dConstE2: .double 0f1E2
dConstE1: .double 0f1E1
dConstME5: .double 0f1E-5
dConstME255: .double 0f1E-255
dConstME127: .double 0f1E-127
dConstME63: .double 0f1E-63
dConstME31: .double 0f1E-31
dConstME15: .double 0f1E-15
dConstME7: .double 0f1E-7
dConstME3: .double 0f1E-3
dConstME1: .double 0f1E-1
dConstE0: .double 0f1E0
 
/******************************************************************/
/* Décimal Conversion */
/******************************************************************/
/* x0 contain value et x1 address conversion area */
conversion10SP:
stp x1,lr,[sp,-16]! // save registers
stp x2,x3,[sp,-16]! // save registers
stp x4,x5,[sp,-16]! // save registers
mov x5,x1
mov x4,#16
mov x2,x0
mov x1,#10 // décimal conversion
1: // conversion loop
mov x0,x2 // copy begin number or quotient
udiv x2,x0,x1 // division by 10
msub x3,x1,x2,x0 // compute remainder
add x3,x3,#48 // compute digit
strb w3,[x5,x4] // store byte address area (x5) + offset (x4)
subs x4,x4,#1 // position precedente
bge 1b
strb wzr,[x5,16] // 0 final
100:
ldp x4,x5,[sp],16 // restaur registers
ldp x2,x3,[sp],16 // restaur registers
ldp x1,lr,[sp],16 // restaur registers
ret
 
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeARM64.inc"
 
</syntaxhighlight>
{{Out}}
<pre>
Result : +4,4
Result : +4,25
</pre>
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
Line 223 ⟶ 815:
>: 48870
=: 0
</pre>
 
=={{header|Amazing Hopper}}==
{{trans|BaCon}}<syntaxhighlight lang="c">
#include <basico.h>
 
#proto cálculodemediana(_X_)
#synon _cálculodemediana obtenermedianade
 
algoritmo
 
decimales '2'
matrices 'a,b'
'4.1, 5.6, 7.2, 1.7, 9.3, 4.4, 3.2', enlistar en 'a'
'4.1, 7.2, 1.7, 9.3, 4.4, 3.2', enlistar en 'b'
arr.ordenar 'a'
arr.ordenar 'b'
"A=",a,NL,"Median: ", obtener mediana de 'a', NL
"B=",b,NL,"Median: ", obtener mediana de 'b', NL
finalmente imprime
 
terminar
 
subrutinas
 
cálculo de mediana (x)
 
dx=0
filas de 'x' ---copiar en 'dx'---
calcular si ( es par?, #( (x[ (dx/2) ]+x[ (dx/2)+1 ])/2 ),\
#( x[ dx/2+1 ] ) )
retornar
</syntaxhighlight>
{{out}}
<pre>
A=1.70,3.20,4.10,4.40,5.60,7.20,9.30
Median: 4.40
B=1.70,3.20,4.10,4.40,7.20,9.30
Median: 4.25
 
</pre>
 
Line 613 ⟶ 1,246:
L = 11 : GOSUB 100MEDIAN
? R</syntaxhighlight>Output:<pre>5.95</pre>
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
<syntaxhighlight lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program averageMed.s */
/* use quickselect look pseudo code in wikipedia quickselect */
 
/************************************/
/* Constantes */
/************************************/
/* for constantes see task include a file in arm assembly */
.include "../constantes.inc"
 
/*********************************/
/* Initialized data */
/*********************************/
.data
szMessResultValue: .asciz "Result : "
szCarriageReturn: .asciz "\n"
.align 4
TableNumber: .float 4.1, 5.6, 7.2, 1.7, 9.3, 4.4, 3.2
.equ NBELEMENTS, (. - TableNumber) / 4
TableNumber2: .float 4.1, 7.2, 1.7, 9.3, 4.4, 3.2
.equ NBELEMENTS2, (. - TableNumber2) / 4
/*********************************/
/* UnInitialized data */
/*********************************/
.bss
sZoneConv: .skip 24
sZoneConv1: .skip 24
/*********************************/
/* code section */
/*********************************/
.text
.global main
main: @ entry of program
 
ldr r0,iAdrTableNumber @ address number table
mov r1,#0 @ index first item
mov r2,#NBELEMENTS -1 @ index last item
bl searchMedian
ldr r0,iAdrTableNumber2 @ address number table 2
mov r1,#0 @ index first item
mov r2,#NBELEMENTS2 -1 @ index last item
bl searchMedian
 
100: @ standard end of the program
mov r0, #0 @ return code
mov r7, #EXIT @ request to exit program
svc #0 @ perform the system call
iAdrszCarriageReturn: .int szCarriageReturn
iAdrTableNumber: .int TableNumber
iAdrTableNumber2: .int TableNumber2
iAdrsZoneConv: .int sZoneConv
iAdrszMessResultValue: .int szMessResultValue
/***************************************************/
/* search median term in float array */
/***************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item */
/* r2 contains index of last item */
searchMedian:
push {r1-r5,lr} @ save registers
mov r5,r0 @ save array address
add r4,r1,r2
add r4,r4,#1 @ sum numbers terms
tst r4,#1 @ odd ?
bne 1f
lsr r3,r4,#1 @ compute median index
bl select @ call selection
vmov s0,r0 @ save first result
sub r3,r3,#1 @ second term
mov r0,r5
bl select @ call selection
vmov s1,r0 @ save 2ieme résult
vadd.f32 s0,s1 @ compute average two résults
mov r0,#2
vmov s1,r0
vcvt.f32.u32 s1,s1 @ conversion integer -> float
vdiv.f32 s0,s0,s1
b 2f
1: @ even
lsr r3,r4,#1
bl select @ call selection
vmov s0,r0
2:
ldr r0,iAdrsZoneConv @ conversion float in decimal string
bl convertirFloat
mov r0,#3 @ and display result
ldr r1,iAdrszMessResultValue
ldr r2,iAdrsZoneConv
ldr r3,iAdrszCarriageReturn
bl displayStrings
100: @ end function
pop {r1-r5,pc} @ restaur register
/***************************************************/
/* Appel récursif selection */
/***************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item */
/* r2 contains index of last item */
/* r3 contains search index */
/* r0 return final value in float */
/* remark : the final result is a float returned in r0 register */
select:
push {r1-r6,lr} @ save registers
mov r6,r3 @ save search index
cmp r1,r2 @ first = last ?
ldreq r0,[r0,r1,lsl #2] @ return value of first index
beq 100f @ yes -> end
add r3,r1,r2
lsr r3,r3,#1 @ compute median pivot
mov r4,r0 @ save r0
mov r5,r2 @ save r2
bl partition @ cutting into 2 parts
cmp r6,r0 @ pivot is ok ?
ldreq r0,[r4,r0,lsl #2] @ return value
beq 100f
bgt 1f
sub r2,r0,#1 @ index partition - 1
mov r0,r4 @ array address
mov r3,r6 @ search index
bl select @ select lower part
b 100f
1:
add r1,r0,#1 @ index begin = index partition + 1
mov r0,r4 @ array address
mov r2,r5 @ last item
mov r3,r6 @ search index
bl select @ select higter part
100: @ end function
pop {r1-r6,pc} @ restaur register
/******************************************************************/
/* Partition table elements */
/******************************************************************/
/* r0 contains the address of table */
/* r1 contains index of first item */
/* r2 contains index of last item */
/* r3 contains index of pivot */
partition:
push {r1-r6,lr} @ save registers
ldr r4,[r0,r3,lsl #2] @ load value of pivot
ldr r5,[r0,r2,lsl #2] @ load value last index
str r5,[r0,r3,lsl #2] @ swap value of pivot
str r4,[r0,r2,lsl #2] @ and value last index
mov r3,r1 @ init with first index
1: @ begin loop
ldr r6,[r0,r3,lsl #2] @ load value
cmp r6,r4 @ compare loop value and pivot value
ldrlt r5,[r0,r1,lsl #2] @ if < swap value table
strlt r6,[r0,r1,lsl #2]
strlt r5,[r0,r3,lsl #2]
addlt r1,#1 @ and increment index 1
add r3,#1 @ increment index 2
cmp r3,r2 @ end ?
blt 1b @ no loop
ldr r5,[r0,r1,lsl #2] @ swap value
str r4,[r0,r1,lsl #2]
str r5,[r0,r2,lsl #2]
mov r0,r1 @ return index partition
100:
pop {r1-r6,pc}
/***************************************************/
/* display multi strings */
/***************************************************/
/* r0 contains number strings address */
/* r1 address string1 */
/* r2 address string2 */
/* r3 address string3 */
/* other address on the stack */
/* thinck to add number other address * 4 to add to the stack */
displayStrings: @ INFO: displayStrings
push {r1-r4,fp,lr} @ save des registres
add fp,sp,#24 @ save paraméters address (6 registers saved * 4 bytes)
mov r4,r0 @ save strings number
cmp r4,#0 @ 0 string -> end
ble 100f
mov r0,r1 @ string 1
bl affichageMess
cmp r4,#1 @ number > 1
ble 100f
mov r0,r2
bl affichageMess
cmp r4,#2
ble 100f
mov r0,r3
bl affichageMess
cmp r4,#3
ble 100f
mov r3,#3
sub r2,r4,#4
1: @ loop extract address string on stack
ldr r0,[fp,r2,lsl #2]
bl affichageMess
subs r2,#1
bge 1b
100:
pop {r1-r4,fp,pc}
/******************************************************************/
/* Conversion Float */
/******************************************************************/
/* s0 contains Float */
/* r0 contains address conversion area mini 20 charactèrs*/
/* r0 return result length */
/* see https://blog.benoitblanchon.fr/lightweight-float-to-string/ */
convertirFloat:
push {r1-r7,lr}
vpush {s0-s2}
mov r6,r0 @ save area address
vmov r0,s0
mov r1,#0
vmov s1,r1
movs r7,#0 @ result length
movs r3,#'+'
strb r3,[r6] @ sign + forcing
mov r2,r0
lsls r2,#1 @ extraction bit 31
bcc 1f @ positive ?
lsrs r0,r2,#1 @ raz sign if negative
movs r3,#'-' @ sign -
strb r3,[r6]
1:
adds r7,#1 @ next position
cmp r0,#0 @ case of positive or negative 0
bne 2f
movs r3,#'0'
strb r3,[r6,r7] @ store character 0
adds r7,#1 @ next position
movs r3,#0
strb r3,[r6,r7] @ store 0 final
mov r0,r7 @ return length
b 100f @ and end
2:
ldr r2,iMaskExposant
mov r1,r0
ands r1,r2 @ exposant = 255 ?
cmp r1,r2
bne 4f
lsls r0,#10 @ bit 22 à 0 ?
bcc 3f @ yes
movs r2,#'N' @ case of Nan. store byte, if not possible store int
strb r2,[r6] @ area no aligned
movs r2,#'a'
strb r2,[r6,#1]
movs r2,#'n'
strb r2,[r6,#2]
movs r2,#0 @ 0 final
strb r2,[r6,#3]
movs r0,#3 @ return length 3
b 100f
3: @ case infini positive or négative
movs r2,#'I'
strb r2,[r6,r7]
adds r7,#1
movs r2,#'n'
strb r2,[r6,r7]
adds r7,#1
movs r2,#'f'
strb r2,[r6,r7]
adds r7,#1
movs r2,#0
strb r2,[r6,r7]
mov r0,r7
b 100f
4:
bl normaliserFloat
mov r5,r0 @ save exposant
VCVT.U32.f32 s2,s0 @ integer value of integer part
vmov r0,s2 @ integer part
VCVT.F32.U32 s1,s2 @ conversion float
vsub.f32 s1,s0,s1 @ extraction fract part
vldr s2,iConst1
vmul.f32 s1,s2,s1 @ to crop it in full
 
VCVT.U32.f32 s1,s1 @ integer conversion
vmov r4,s1 @ fract value
@ integer conversion in r0
mov r2,r6 @ save address area begin
adds r6,r7
mov r1,r6
bl conversion10
add r6,r0
movs r3,#','
strb r3,[r6]
adds r6,#1
mov r0,r4 @ conversion fractional part
mov r1,r6
bl conversion10SP @ spécial routine with conservation begin 0
add r6,r0
subs r6,#1
@ remove trailing zeros
5:
ldrb r0,[r6]
cmp r0,#'0'
bne 6f
subs r6,#1
b 5b
6:
cmp r0,#','
bne 7f
subs r6,#1
7:
adds r6,#1
movs r3,#'E'
strb r3,[r6]
adds r6,#1
mov r0,r5 @ conversion exposant
mov r3,r0
lsls r3,#1
bcc 4f
rsbs r0,r0,#0
movs r3,#'-'
strb r3,[r6]
adds r6,#1
4:
mov r1,r6
bl conversion10
add r6,r0
movs r3,#0
strb r3,[r6]
adds r6,#1
mov r0,r6
subs r0,r2 @ return length result
subs r0,#1 @ - 0 final
 
100:
vpop {s0-s2}
pop {r1-r7,pc}
iMaskExposant: .int 0xFF<<23
iConst1: .float 0f1E9
 
/***************************************************/
/* normaliser float */
/***************************************************/
/* r0 contain float value (always positive value and <> Nan) */
/* s0 return new value */
/* r0 return exposant */
normaliserFloat:
push {lr} @ save registre
vmov s0,r0 @ value float
movs r0,#0 @ exposant
vldr s1,iConstE7 @ no normalisation for value < 1E7
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
blo 10f @ if s0 < iConstE7
vldr s1,iConstE32
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
blo 1f
vldr s1,iConstE32
vdiv.f32 s0,s0,s1
adds r0,#32
1:
vldr s1,iConstE16
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
blo 2f
vldr s1,iConstE16
vdiv.f32 s0,s0,s1
adds r0,#16
2:
vldr s1,iConstE8
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
blo 3f
vldr s1,iConstE8
vdiv.f32 s0,s0,s1
adds r0,#8
3:
vldr s1,iConstE4
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
blo 4f
vldr s1,iConstE4
vdiv.f32 s0,s0,s1
adds r0,#4
4:
vldr s1,iConstE2
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
blo 5f
vldr s1,iConstE2
vdiv.f32 s0,s0,s1
adds r0,#2
5:
vldr s1,iConstE1
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
blo 10f
vldr s1,iConstE1
vdiv.f32 s0,s0,s1
adds r0,#1
 
10:
vldr s1,iConstME5 @ pas de normalisation pour les valeurs > 1E-5
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
bhi 100f
vldr s1,iConstME31
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
bhi 11f
vldr s1,iConstE32
 
vmul.f32 s0,s0,s1
subs r0,#32
11:
vldr s1,iConstME15
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
bhi 12f
vldr s1,iConstE16
vmul.f32 s0,s0,s1
subs r0,#16
12:
vldr s1,iConstME7
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
bhi 13f
vldr s1,iConstE8
vmul.f32 s0,s0,s1
subs r0,#8
13:
vldr s1,iConstME3
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
bhi 14f
vldr s1,iConstE4
vmul.f32 s0,s0,s1
subs r0,#4
14:
vldr s1,iConstME1
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
bhi 15f
vldr s1,iConstE2
vmul.f32 s0,s0,s1
subs r0,#2
15:
vldr s1,iConstE0
vcmp.f32 s0,s1
vmrs APSR_nzcv,FPSCR
bhi 100f
vldr s1,iConstE1
vmul.f32 s0,s0,s1
subs r0,#1
 
100: @ fin standard de la fonction
pop {pc} @ restaur des registres
.align 2
iConstE7: .float 0f1E7
iConstE32: .float 0f1E32
iConstE16: .float 0f1E16
iConstE8: .float 0f1E8
iConstE4: .float 0f1E4
iConstE2: .float 0f1E2
iConstE1: .float 0f1E1
iConstME5: .float 0f1E-5
iConstME31: .float 0f1E-31
iConstME15: .float 0f1E-15
iConstME7: .float 0f1E-7
iConstME3: .float 0f1E-3
iConstME1: .float 0f1E-1
iConstE0: .float 0f1E0
/******************************************************************/
/* Décimal Conversion */
/******************************************************************/
/* r0 contain value et r1 address conversion area */
conversion10SP:
push {r1-r6,lr} @ save registers
mov r5,r1
mov r4,#8
mov r2,r0
mov r1,#10 @ conversion decimale
1: @ begin loop
mov r0,r2 @ copy number or quotients
bl division @ r0 dividende r1 divisor r2 quotient r3 remainder
add r3,#48 @ compute digit
strb r3,[r5,r4] @ store byte area address (r5) + offset (r4)
subs r4,r4,#1 @ position précedente
bge 1b @ and loop if not < zero
mov r0,#8
mov r3,#0
strb r3,[r5,r0] @ store 0 final
100:
pop {r1-r6,pc} @ restaur registers
/***************************************************/
/* ROUTINES INCLUDE */
/***************************************************/
/* for this file see task include a file in language ARM assembly */
.include "../affichage.inc"
 
</syntaxhighlight>
{{Out}}
<pre>
Result : +4,40000009E0
Result : +4,25E0
</pre>
 
=={{header|Arturo}}==
Line 792 ⟶ 1,929:
=={{header|Bracmat}}==
 
Each number is packaged in a little structure and these structures are accumulated in a sum. Bracmat keeps sums sorted, so the median is the term in the middle of the list, or the average of the two terms in the middle of the list. Notice that the input is converted to Bracmat's internal number representation, rational numbers, before being sorted. The output is converted back to 'double' variables. That last conversion is lossy.
Bracmat has no floating point numbers, so we have to parse floating point numbers as strings and convert them to rational numbers.
Each number is packaged in a little list and these lists are accumulated in a sum. Bracmat keeps sums sorted, so the median is the term in the middle of the list, or the average of the two terms in the middle of the list.
 
<syntaxhighlight lang="bracmat">( ( median=
= begin decimals end int list
begin decimals end int list med med1 med2 num number
, med med1 med2 num number
. 0:?list
. ( convertToRational
& whl
' ( @( !arg =
: . new$(UFP,'(.$arg:?V))
((%@:~" ":~",") ?:?number)ufp
& ((" "|",") ?arg|:?argufp..go)$
& (ufp..export)$(Q.V)
& @( !number)
& 0:?list
: ( #?int "." [?begin #?decimals [?end
& whl
& !int+!decimals*10^(!begin+-1*!end):?num
' ( |!arg:%?number ?numarg
& )convertToRational$!number:?rationalnumber
& (!rationalnumber.)+!list:?list
& (!num. )+!list:?list
& !list:?+[?end
& ( !end*1/2:~/
& !list
: ?
+ [!(=1/2*!end+-1)
+ (?med1.?)
+ (?med2.?)
+ ?
& !med1*1/2+!med2*1/2:?med
| !list:?+[(div$(1/2*!end,1))+(?med.)+?
)
& (new$(UFP,'(.$med)).go)$
)
& out$(median$("4.1" 4 "1.2" "6.235" "7868.33"))
& out
$ ( median
$ ( "4.4"
"2.3"
"-1.7"
"7.5"
"6.6"
"0.0"
"1.9"
"8.2"
"9.3"
"4.5"
)
& !list:?+[?end
& ( !end*1/2:~/
& !list:?+[!(=1/2*!end+-1)+(?med1.)+(?med2.)+?
& !med1*1/2+!med2*1/2:?med
| !list:?+[(div$(1/2*!end,1))+(?med.)+?
)
& out$(median$(1 5 3 2 4))
& !med
& out$(median$(1 5 3 6 4 2))
);</syntaxhighlight>
 
Output:
<pre>4.0999999999999996E+00
<pre> median$" 4.1 4 1.2 6.235 7868.33"
4.4500000000000002E+00
41/10
3.0000000000000000E+00
 
3.5000000000000000E+00</pre>
median$"4.4, 2.3, -1.7, 7.5, 6.6, 0.0, 1.9, 8.2, 9.3, 4.5"
89/20
 
median$"1, 5, 3, 2, 4"
3
 
median$"1, 5, 3, 6, 4, 2"
7/2</pre>
 
=={{header|C}}==
Line 957 ⟶ 2,109:
 
=={{header|C sharp|C#}}==
{{works with|C sharp|C#|10+}}
<syntaxhighlight lang="csharp">using System;
<syntaxhighlight lang="csharp">
using System.Linq;
double median(double[] arr)
 
namespace Test
{
var sorted = arr.OrderBy(x => x).ToList();
class Program
var mid = arr.Length / 2;
{
return arr.Length % 2 == 0
static void Main()
? (sorted[mid] + sorted[mid-1]) / 2
{
: sorted[mid];
double[] myArr = new double[] { 1, 5, 3, 6, 4, 2 };
}
 
var write = (double[] x) =>
myArr = myArr.OrderBy(i => i).ToArray();
Console.WriteLine($"[{string.Join(", ", x)}]: {median(x)}");
// or Array.Sort(myArr) for in-place sort
write(new double[] { 1, 5, 3, 6, 4, 2 }); //even
 
write(new double[] { 1, 5, 3, 6, 4, 2, 7 }); //odd
int mid = myArr.Length / 2;
write(new double[] { 5 }); //single
double median;
 
if (myArr.Length % 2 == 0)
{
//we know its even
median = (myArr[mid] + myArr[mid - 1]) / 2.0;
}
else
{
//we know its odd
median = myArr[mid];
}
 
Console.WriteLine(median);
Console.ReadLine();
}
}
}
</syntaxhighlight>
{{output}}
<pre>
[1, 5, 3, 6, 4, 2]: 3.5
[1, 5, 3, 6, 4, 2, 7]: 4
[5]: 5
</pre>
 
=={{header|C++}}==
Line 1,112 ⟶ 2,253:
(defun median (list predicate)
(select-nth (floor (length list) 2) list predicate))</syntaxhighlight>
 
=={{header|Craft Basic}}==
<syntaxhighlight lang="basic">define limit = 10, iterations = 6
define iteration, size, middle, plusone
define point, top, high, low, pivot
 
dim list[limit]
dim stack[limit]
 
for iteration = 1 to iterations
 
gosub fill
gosub median
 
next iteration
 
end
 
sub fill
 
print "list: ",
 
erasearray list
 
let size = int(rnd * limit) + 1
 
if size <= 2 then
 
let size = 3
 
endif
 
for i = 0 to size - 1
 
let list[i] = rnd * 1000 + rnd
print list[i],
 
gosub printcomma
 
next i
 
return
 
sub median
 
gosub sort
 
print newline, "size: ", size, tab,
 
let middle = int((size - 1)/ 2)
print "middle: ", middle + 1, tab,
 
if size mod 2 then
 
print "median: ", list[middle]
 
else
 
let plusone = middle + 1
print "median: ", (list[middle] + list[plusone]) / 2
 
endif
 
print
 
return
 
sub sort
 
let low = 0
let high = size - 1
let top = -1
 
let top = top + 1
let stack[top] = low
let top = top + 1
let stack[top] = high
do
 
if top < 0 then
 
break
 
endif
 
let high = stack[top]
let top = top - 1
let low = stack[top]
let top = top - 1
 
let i = low - 1
for j = low to high - 1
 
if list[j] <= list[high] then
 
let i = i + 1
let t = list[i]
let list[i] = list[j]
let list[j] = t
 
endif
 
next j
 
let point = i + 1
let t = list[point]
let list[point] = list[high]
let list[high] = t
let pivot = i + 1
 
if pivot - 1 > low then
 
let top = top + 1
let stack[top] = low
let top = top + 1
let stack[top] = pivot - 1
 
endif
if pivot + 1 < high then
 
let top = top + 1
let stack[top] = pivot + 1
let top = top + 1
let stack[top] = high
 
endif
 
wait
 
loop top >= 0
 
print newline, "sorted: ",
 
for i = 0 to size - 1
 
print list[i],
gosub printcomma
 
next i
 
return
 
sub printcomma
 
if i < size - 1 then
 
print comma, " ",
 
endif
 
return</syntaxhighlight>
{{out| Output}}
<pre>
list: 290.66, 870.46, 880.86
sorted: 290.66, 870.46, 880.86
size: 3 middle: 2 median: 870.46
 
list: 910.91, 50.79, 790.58, 960.61
sorted: 50.79, 790.58, 910.91, 960.61
size: 4 middle: 2 median: 850.74
 
list: 570.31, 500.16, 490.97, 370.48, 240.18, 880.23, 190.61, 950.19
sorted: 190.61, 240.18, 370.48, 490.97, 500.16, 570.31, 880.23, 950.19
size: 8 middle: 4 median: 495.57
 
list: 120.87, 570.87, 570.85, 800.27, 200.04, 250.09, 870.04, 200.58, 800.61
sorted: 120.87, 200.04, 200.58, 250.09, 570.85, 570.87, 800.27, 800.61, 870.04
size: 9 middle: 5 median: 570.85
 
list: 810.33, 760.55, 420.22, 730.64, 350.96
sorted: 350.96, 420.22, 730.64, 760.55, 810.33
size: 5 middle: 3 median: 730.64
 
list: 40.12, 860.77, 960.29, 920.13
sorted: 40.12, 860.77, 920.13, 960.29
size: 4 middle: 2 median: 890.45
</pre>
 
=={{header|Crystal}}==
Line 1,208 ⟶ 2,529:
 
<syntaxhighlight lang="text">
funcproc quickselect k . list[] res .
#
subr partition
mid = left
for i = left + 1 to right
if list[i] < list[left]
mid += 1
swap list[i] list[mid]
.
.
swap list[left] list[mid]
.
.
swap list[left] list[mid]
left = 1
.
left right = 1len list[]
while left < right
right = len list[]
partition
while left < right
call partition if mid < k
if left = mid <+ k1
left =elif mid +> 1k
elif right = mid >- k1
right = mid - 1else
left = right
else
left = right.
.
res = list[k]
.
res = list[k]
.
funcproc median . list[] res .
h = len list[] div 2 + 1
call quickselect h list[] res
if len list[] mod 2 = 0
call quickselect h - 1 list[] h
res = (res + h) / 2
.
.
test[] = [ 4.1 5.6 7.2 1.7 9.3 4.4 3.2 ]
call median test[] med
print med
test[] = [ 4.1 7.2 1.7 9.3 4.4 3.2 ]
call median test[] med
print med
</syntaxhighlight>
Line 1,275 ⟶ 2,596:
 
=={{header|Elena}}==
ELENA 56.0x :
<syntaxhighlight lang="elena">import system'routines;
import system'math;
Line 1,294 ⟶ 2,615:
{
var middleIndex := len / 2;
if (len.mod:(2) == 0)
{
^ (sorted[middleIndex - 1] + sorted[middleIndex]) / 2
Line 1,350 ⟶ 2,671:
[3, 2, 6, 3, 2] => 3
[6, 4, 2, 3, 1, 3] => 3.0
</pre>
 
=={{header|EMal}}==
===Sort===
<syntaxhighlight lang="emal">
fun median = real by some real values
values = values.sort()
int mid = values.length / 2
return when(values.length % 2 == 0, (values[mid] + values[mid - 1]) / 2.0, values[mid])
end
writeLine(median(4.1, 5.6, 7.2, 1.7, 9.3, 4.4, 3.2, 5.0))
</syntaxhighlight>
{{out}}
<pre>
4.7
</pre>
===Quickselect===
<syntaxhighlight lang="emal">
fun median = real by some real values
fun swap = void by int a, int b
real t = values[a]
values[a] = values[b]
values[b] = t
end
fun select = real by int k
int left = 0
int right = values.length - 1
while left < right
real pivot = values[k]
swap(k, right)
int pos = left
for int i = left; i < right; i++
if values[i] < pivot
swap(i, pos)
++pos
end
end
swap(right, pos)
if pos == k do break
else if pos < k do left = pos + 1
else do right = pos - 1 end
end
return values[k]
end
int halfLength = values.length / 2
return when(values.length % 2 == 0,
(select(halfLength) + select(halfLength - 1)) / 2.0,
select(halfLength))
end
writeLine(median(4.1, 5.6, 7.2, 1.7, 9.3, 4.4, 3.2, 5.0))
</syntaxhighlight>
{{out}}
<pre>
4.7
</pre>
 
Line 1,805 ⟶ 3,180:
Median for first 9 elements : 4.4
</pre>
 
=={{header|FutureBasic}}==
FB has native averaging functions.
<syntaxhighlight lang="futurebasic">
local fn MedianAverage( arguments as CFArrayRef ) as CFStringRef
ExpressionRef expRef = fn ExpressionForFunction( @"median:", @[fn ExpressionForConstantValue( arguments )] )
CFNumberRef result = fn ExpressionValueWithObject( expRef, NULL, NULL )
CFStringRef median = fn NumberStringValue( result )
end fn = median
 
print fn MedianAverage( @[@1, @9, @2] ) // 2
print fn MedianAverage( @[@1, @9, @2, @4] ) // 3
print fn MedianAverage( @[@5.961475, @2.025856, @7.262835, @1.814272, @2.281911, @4.854716] ) // 3.5683135
print fn MedianAverage( @[@4.1, @5.6, @7.2, @1.7, @9.3, @4.4, @3.2] ) // 4.4
print fn MedianAverage( @[@40.12, @860.77, @960.29, @920.13] ) // 890.45
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
2
3
3.5683135
4.4
890.45
 
</pre>
 
 
 
 
=={{header|GAP}}==
Line 2,074 ⟶ 3,479:
 
Sorting:
<syntaxhighlight lang="java5java">// Note: this function modifies the input list
public static double median(List<Double> listvalues) {
/* copy, as to prevent modifying 'values' */
List<Double> list = new ArrayList<>(values);
Collections.sort(list);
/* 'mid' will be truncated */
return (list.get(list.size() / 2) + list.get((list.size() - 1) / 2)) / 2;
int mid = list.size() / 2;
}</syntaxhighlight>
return switch (list.size() % 2) {
case 0 -> {
double valueA = list.get(mid);
double valueB = list.get(mid + 1);
yield (valueA + valueB) / 2;
}
case 1 -> list.get(mid);
default -> 0;
};
}
</syntaxhighlight>
 
{{works with|Java|1.5+}}
Line 2,308 ⟶ 3,726:
median(listOf(3.0, 4.0, 1.0, -8.4, 7.2, 4.0, 1.0, 1.2)).let { println(it) } // 2.1
}</syntaxhighlight>
 
 
=={{header|Lambdatalk}}==
{{trans|11l}}
<syntaxhighlight lang="scheme">
{def median
{lambda {:s}
{let { {:a {A.sort! < {A.new :s}}}
{:len {S.length :s}}
} {* 0.5 {+ {A.get {floor {/ {- :len 1} 2}} :a}
{A.get {floor {/ :len 2}} :a} }} }}}
-> median
 
{median 4.1 5.6 7.2 1.7 9.3 4.4 3.2}
-> 4.4
{median 4.1 7.2 1.7 9.3 4.4 3.2}
-> 4.25
</syntaxhighlight>
 
=={{header|Lasso}}==
Line 2,548 ⟶ 3,984:
median([41, 56, 72, 17, 93, 44, 32]); /* 44 */
median([41, 72, 17, 93, 44, 32]); /* 85/2 */</syntaxhighlight>
 
=={{header|min}}==
<syntaxhighlight lang="min">('> sort med) ^median
 
(4.1 5.6 7.2 1.7 9.3 4.4 3.2) median puts!
(4.1 7.2 1.7 9.3 4.4 3.2) median puts!</syntaxhighlight>
{{out}}
<pre>4.4
4.25</pre>
 
=={{header|MiniScript}}==
Line 3,557 ⟶ 5,002:
else return srtd[ceil(alen/2)] ok
</syntaxhighlight>
 
=={{header|RPL}}==
≪ '''SORT'''
DUP SIZE 1 + 2 /
DUP2 FLOOR GET ROT ROT CEIL GET + 2 /
≫ ''''MDIAN'''' STO
<code>SORT</code> became a standard RPL instruction in 1993, with the introduction of the HP-48G. For earlier RPL versions, users have to call the sorting program demonstrated [[Sorting algorithms/Bubble sort#RPL|here]].
 
=={{header|Ruby}}==
Line 3,787 ⟶ 5,239:
calcmedian x
display r(p50)</syntaxhighlight>
=={{header|Swift}}==
===A full implementation===
<syntaxhighlight lang="swift">
// Utility to aid easy type conversion
extension Double {
init(withNum v: any Numeric) {
switch v {
case let ii as any BinaryInteger: self.init(ii)
case let ff as any BinaryFloatingPoint: self.init(ff)
default: self.init()
}
}
}
 
extension Array where Element: Numeric & Comparable {
// Helper func for random element in range
func randomElement(within: Range<Int>) -> Element {
return self[.random(in: within)]
}
 
mutating func median() -> Double? {
switch self.count {
case 0: return nil
case 1: return Double(withNum: self[0])
case 2: return self.reduce(0, {sum,this in sum + Double(withNum: this)/2.0})
default: break
}
let pTarget: Int = self.count / 2 + 1
let resultSetLen: Int = self.count.isMultiple(of: 2) ? 2 : 1
func divideAndConquer(bottom: Int, top: Int, goal: Int) -> Int {
var (lower,upper) = (bottom,top)
while true {
let splitVal = self.randomElement(within: lower..<upper)
let partitionIndex = self.partition(subrange: lower..<upper, by: {$0 > splitVal})
switch partitionIndex {
case goal: return partitionIndex
case ..<goal: lower = partitionIndex
default: upper = partitionIndex
}
}
}
// Split just above the 'median point'
var pIndex = divideAndConquer(bottom: 0, top: self.count, goal: pTarget)
// Shove the highest 'low' values into the result slice
pIndex = divideAndConquer(bottom: 0, top: pIndex, goal: pIndex - resultSetLen)
// Average the contents of the result slice
return self[pIndex..<pIndex + resultSetLen]
.reduce(0.0, {sum,this in sum + Double(withNum: this)/Double(withNum: resultSetLen)})
}
}
</syntaxhighlight>
Usage:
<syntaxhighlight lang="swift">
var c: [Double] = (0...100).map {_ in Double.random(in: 0...100)}
print(c.median())
 
</syntaxhighlight>
 
=={{header|Tcl}}==
Line 3,939 ⟶ 5,448:
{{libheader|Wren-math}}
{{libheader|Wren-queue}}
<syntaxhighlight lang="ecmascriptwren">import "./sort" for Sort, Find
import "./math" for Nums
import "./queue" for PriorityQueue
 
var lists = [
Line 3,981 ⟶ 5,490:
2.1
2.1
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">func real Median(Size, Array); \Return median value of Array
int Size; real Array;
int I, J, MinJ;
real Temp;
[for I:= 0 to Size/2 do \partial selection sort
[MinJ:= I;
for J:= I+1 to Size-1 do
if Array(J) < Array(MinJ) then MinJ:= J;
Temp:= Array(I); Array(I):= Array(MinJ); Array(MinJ):= Temp;
];
if rem(Size/2) = 1 then return Array(Size/2)
else return (Array(Size/2-1) + Array(Size/2)) / 2.;
];
 
[RlOut(0, Median(3, [5.0, 3.0, 4.0])); CrLf(0);
RlOut(0, Median(8, [3.0, 4.0, 1.0, -8.4, 7.2, 4.0, 1.0, 1.2])); CrLf(0);
]</syntaxhighlight>
{{out}}
<pre>
4.00000
2.10000
</pre>
 
5

edits