Movatterモバイル変換


[0]ホーム

URL:


Jump to content
Rosetta Code
Search

Angle difference between two bearings

From Rosetta Code
Task
Angle difference between two bearings
You are encouraged tosolve this task according to the task description, using any language you may know.

Finding the angle between two bearings is often confusing.[1]


Task

Find the angle which is the result of the subtractionb2 - b1, whereb1 andb2 are the bearings.


Input bearings are expressed in the range  -180   to  +180   degrees.
The  result  is also expressed in the range  -180   to  +180   degrees.


Compute the angle for the following pairs:

  • 20 degrees (b1) and 45 degrees (b2)
  • -45 and 45
  • -85 and 90
  • -95 and 90
  • -45 and 125
  • -45 and 145
  • 29.4803 and -88.6381
  • -78.3251 and -159.036


Optional extra

Allow the input bearings to be any (finite) value.


Test cases
  • -70099.74233810938 and 29840.67437876723
  • -165313.6666297357 and 33693.9894517456
  • 1174.8380510598456 and -154146.66490124757
  • 60175.77306795546 and 42213.07192354373



11l

F get_difference(b1, b2)   R wrap(b2 - b1, -180.0, 180.0)print(get_difference( 20.0, 45.0))print(get_difference(-45.0, 45.0))print(get_difference(-85.0, 90.0))print(get_difference(-95.0, 90.0))print(get_difference(-45.0, 125.0))print(get_difference(-45.0, 145.0))print(get_difference(-45.0, 125.0))print(get_difference(-45.0, 145.0))print(get_difference(29.4803, -88.6381))print(get_difference(-78.3251, -159.036))print(‘’)print(get_difference(-70099.74233810938, 29840.67437876723))print(get_difference(-165313.6666297357, 33693.9894517456))print(get_difference(1174.8380510598456, -154146.66490124757))print(get_difference(60175.77306795546, 42213.07192354373))
Output:
2590175-175170-170170-170-118.118-80.7109-139.583-72.3439-161.50337.2989

360 Assembly

Translation of:Rexx
*        Angle difference between two bearings - 06/06/2018ANGLEDBB CSECT         USING  ANGLEDBB,R13       base register         B      72(R15)            skip savearea         DC     17F'0'             savearea         SAVE   (14,12)            save previous context         ST     R13,4(R15)         link backward         ST     R15,8(R13)         link forward         LR     R13,R15            set addressability         LA     R10,T-4            @t         LA     R6,1               i=1       DO WHILE=(C,R6,LE,N)        do i=1 to n         LA     R10,4(R10)           next @t         L      R7,0(R10)            a=t(i,1)         LA     R10,4(R10)           next @t         L      R8,0(R10)            b=t(i,2)         LR     R4,R8                b         SR     R4,R7                b-a         SRDA   R4,32                ~         D      R4,=F'3600000'       /360         A      R4,=F'5400000'       +540         SRDA   R4,32                ~         D      R4,=F'3600000'       /360         S      R4,=F'1800000'       x=((((b-a)//360)+540)//360)-180                  XDECO  R7,XDEC              edit a         MVC    PG(8),XDEC           output a         MVC    PG+9(4),XDEC+8       output a decimals         XDECO  R8,XDEC              edit b         MVC    PG+14(8),XDEC        output b         MVC    PG+23(4),XDEC+8      output b decimals         XDECO  R4,XDEC              edit x         MVC    PG+28(8),XDEC        output x         MVC    PG+37(4),XDEC+8      output x decimals         XPRNT  PG,L'PG              print         LA     R6,1(R6)             i++       ENDDO    ,                  enddo i         L      R13,4(0,R13)       restore previous savearea pointer         RETURN (14,12),RC=0       restore registers from calling savN        DC     F'8'               number of pairsT        DC     F'200000',F'450000',F'-450000',F'450000'         DC     F'-850000',F'900000',F'-950000',F'900000'         DC     F'-450000',F'1250000',F'450000',F'1450000'         DC     F'294803',F'-886361',F'-783251',F'-1590360'PG       DC     CL80'12345678.1234 12345678.1234 12345678.1234'XDEC     DS     CL12               temp         YREGS         END    ANGLEDBB
Output:
      20.0000       45.0000       25.0000     -45.0000       45.0000       90.0000     -85.0000       90.0000      175.0000     -95.0000       90.0000     -175.0000     -45.0000      125.0000      170.0000      45.0000      145.0000      100.0000      29.4803      -88.6361     -118.1164     -78.3251     -159.0360      -80.7109

AArch64 Assembly

Works with:as version Raspberry Pi 3B version Buster 64 bits
or android 64 bits with application Termux
/* ARM assembly AARCH64 Raspberry PI 3B *//*  program diffAngle64.s   *//************************************//* Constantes                       *//************************************/.include "../includeConstantesARM64.inc" /*********************************//* Initialized data              *//*********************************/.dataszCarriageReturn:   .asciz "\n"szMessResult:       .asciz "Difference between @ and @ = @ \n".align 8fB1:            .double 0F20.0fB2:            .double 0F45.0fB3:            .double 0F-45.0fB4:            .double 0F-85.0fB5:            .double 90.0fB6:            .double -95.0fB7:            .double 125.0fB8:            .double 145.0fB9:            .double 0F29.4803 fB10:           .double 0F-88.6381fB11:           .double 0F-78.3251fB12:           .double 0F-159.036fB13:           .double 0F-70099.74233810938fB14:           .double 0F29840.67437876723/*********************************//* UnInitialized data            *//*********************************/.bss  sZoneConv:           .skip 24/*********************************//*  code section                 *//*********************************/.text.global main main:    ldr x0,qAdrfB1    ldr x1,qAdrfB2    bl testComputeAngle    //b 100f    ldr x0,qAdrfB3    ldr x1,qAdrfB2    bl testComputeAngle        ldr x0,qAdrfB4    ldr x1,qAdrfB5    bl testComputeAngle        ldr x0,qAdrfB6    ldr x1,qAdrfB5    bl testComputeAngle    ldr x0,qAdrfB3    ldr x1,qAdrfB7    bl testComputeAngle        ldr x0,qAdrfB3    ldr x1,qAdrfB8    bl testComputeAngle        ldr x0,qAdrfB9    ldr x1,qAdrfB10    bl testComputeAngle    ldr x0,qAdrfB11    ldr x1,qAdrfB12    bl testComputeAngle    ldr x0,qAdrfB13    ldr x1,qAdrfB14    bl testComputeAngle100:                            // standard end of the program     mov x0, #0                  // return code    mov x8,EXIT     svc #0                      // perform the system callqAdrszCarriageReturn:    .quad szCarriageReturnqAdrsZoneConv:           .quad sZoneConv  qAdrfB1:                .quad fB1qAdrfB2:                .quad fB2qAdrfB3:                .quad fB3qAdrfB4:                .quad fB4qAdrfB5:                .quad fB5qAdrfB6:                .quad fB6qAdrfB7:                .quad fB7qAdrfB8:                .quad fB8qAdrfB9:                .quad fB9qAdrfB10:               .quad fB10qAdrfB11:               .quad fB11qAdrfB12:               .quad fB12qAdrfB13:               .quad fB13qAdrfB14:               .quad fB14/******************************************************************//*     compute difference and display result                      */ /******************************************************************//* s0 contains bearing 1  *//* s1 contains bearing 2  */testComputeAngle:    stp x1,lr,[sp,-16]!          // save  registers     stp x2,x3,[sp,-16]!          // save  registers     ldr d0,[x0]    fmov d2,d0    ldr d1,[x1]    bl computeDiffAngle    fmov d3,d0    fmov d0,d2    ldr x0,qAdrsZoneConv    bl convertirFloat    ldr x0,qAdrszMessResult    ldr x1,qAdrsZoneConv    bl strInsertAtCharInc    mov x3,x0    fmov d0,d1    ldr x0,qAdrsZoneConv    bl convertirFloat    mov x0,x3    ldr x1,qAdrsZoneConv    bl strInsertAtCharInc    mov x3,x0    fmov d0,d3    ldr x0,qAdrsZoneConv    bl convertirFloat    mov x0,x3    ldr x1,qAdrsZoneConv    bl strInsertAtCharInc    bl affichageMess     100:    ldp x2,x3,[sp],16        // restaur  registers     ldp x1,lr,[sp],16        // restaur  registers    ret qAdrszMessResult:      .quad szMessResult/******************************************************************//*     compute difference of two bearing                                  */ /******************************************************************//* d0 contains bearing 1  *//* d1 contains bearing 2  */computeDiffAngle:    stp x1,lr,[sp,-16]!        // save  registers     stp x2,x3,[sp,-16]!        // save  registers     stp x4,x5,[sp,-16]!        // save  registers     stp d1,d2,[sp,-16]!        // save  registres    stp d3,d4,[sp,-16]!        // save  registres    mov x1,#360    mov x4,#0                  // top positive/negative    fcvtzs d4,d0               // conversion.integer    scvtf d2,d4                // conversion float    fsub d2,d0,d2              // partie décimale    fmov x0,d4                 // partie entière    cmp x0,#0                  // negative ?    bge 1f    neg x0,x0                  // yes -> inversion     mov x4,#11:    udiv x2,x0,x1              // divide by 360    msub x3,x2,x1,x0    cmp x4,#0                  // value negative ?    neg x5,x3    csel x3,x5,x3,ne           // inversion remainder    fmov d3,x3    scvtf d3,d3                // and conversion float    fadd d0,d3,d2              // add decimal part        mov x4,#0                  // bearing 2    fcvtzs d4,d1               // conversion integer    scvtf d2,d4                // conversion float    fsub d2,d1,d2              // partie décimale    fmov x0,d4    cmp x0,#0    bge 2f    neg x0,x0    mov x4,#12:    udiv x2,x0,x1              // divide by 360    msub x3,x2,x1,x0    cmp x4,#0    neg x5,x3    csel x3,x5,x3,ne           // inversion remainder    fmov d3,x3    scvtf d3,d3                // conversion float    fadd d1,d3,d2          fsub d0,d1,d0              // calculate the difference between the 2 values        mov x0,180    fmov d3,x0    scvtf d3,d3                // conversion float 180    fmov d4,x1                 // 360    scvtf d4,d4                // conversion float 360    fcmp d0,#0.0               // difference is negative ?    blt 2f                               // difference is positive    fcmp d0,d4                 // difference > 360    ble 3f    fsub  d0,d0,d4             // yes -> difference - 3603:    fcmp d0,d3                 // compare difference and 180    ble 100f    fsub d0,d4,d0              // > 180 calculate 360 - difference     fneg d0,d0                 // and negate    b 100f2:                            // différence is négative    fneg d2,d4                // -360    fcmp d0,d2                // compare différence et - 360    ble 3f    fsub  d0,d0,d4            // sub 360 to différence3:    fneg d3,d3                // -180    fcmp d0,d3                // compare difference and -180    bge 100f    fadd d0,d4,d0             // calculate 360 + différence100:    ldp d3,d4,[sp],16         // restaur  registers     ldp d1,d2,[sp],16         // restaur  registers     ldp x4,x5,[sp],16         // restaur  registers     ldp x2,x3,[sp],16         // restaur  registers     ldp x1,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 100f2:     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 100f3:                             // 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 100f4:    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 zeros5:    ldrb w0,[x6]    cmp w0,#'0'    bne 6f    sub x6,x6,#1    b 5b6:    cmp w0,#','    bne 7f    sub x6,x6,#17:      cmp x5,#0                  // if exposant = 0 no display    bne 8f    add x6,x6,#1    b 10f8:    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,#19:    mov x1,x6    bl conversion10    add x6,x6,x010:    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 final100:    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<<52dConst1:                  .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,#2561:        ldr d1,dConstE128    fcmp d0,d1    blo 1f    fdiv d0,d0,d1    adds x0,x0,#1281:    ldr d1,dConstE64    fcmp d0,d1    blo 1f    fdiv d0,d0,d1    adds x0,x0,#641:    ldr d1,dConstE32    fcmp d0,d1    blo 1f    fdiv d0,d0,d1    adds x0,x0,#321:    ldr d1,dConstE16    fcmp d0,d1    blo 2f    fdiv d0,d0,d1    adds x0,x0,#162:    ldr d1,dConstE8    fcmp d0,d1    blo 3f    fdiv d0,d0,d1    adds x0,x0,#83:    ldr d1,dConstE4    fcmp d0,d1    blo 4f    fdiv d0,d0,d1    adds x0,x0,#44:    ldr d1,dConstE2    fcmp d0,d1    blo 5f    fdiv d0,d0,d1    adds x0,x0,#25:    ldr d1,dConstE1    fcmp d0,d1    blo 10f    fdiv d0,d0,d1    adds x0,x0,#110:    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,#25611:        ldr d1,dConstME127    fcmp d0,d1    bhi 11f    ldr d1,dConstE128    fmul d0,d0,d1    subs x0,x0,#12811:        ldr d1,dConstME63    fcmp d0,d1    bhi 11f    ldr d1,dConstE64    fmul d0,d0,d1    subs x0,x0,#6411:       ldr d1,dConstME31    fcmp d0,d1    bhi 11f    ldr d1,dConstE32    fmul d0,d0,d1    subs x0,x0,#3211:    ldr d1,dConstME15    fcmp d0,d1    bhi 12f    ldr d1,dConstE16    fmul d0,d0,d1    subs x0,x0,#1612:    ldr d1,dConstME7    fcmp d0,d1    bhi 13f    ldr d1,dConstE8    fmul d0,d0,d1    subs x0,x0,#813:    ldr d1,dConstME3    fcmp d0,d1    bhi 14f    ldr d1,dConstE4    fmul d0,d0,d1    subs x0,x0,#414:    ldr d1,dConstME1    fcmp d0,d1    bhi 15f    ldr d1,dConstE2    fmul d0,d0,d1    subs x0,x0,#215:    ldr d1,dConstE0    fcmp d0,d1    bhi 100f    ldr d1,dConstE1    fmul d0,d0,d1    subs x0,x0,#1100:                       // fin standard de la fonction    ldp x1,lr,[sp],16           // restaur registres    ret.align 2dConstE7:             .double 0f1E7dConstE256:           .double 0f1E256dConstE128:           .double 0f1E128dConstE64:            .double 0f1E64dConstE32:            .double 0f1E32dConstE16:            .double 0f1E16dConstE8:             .double 0f1E8dConstE4:             .double 0f1E4dConstE2:             .double 0f1E2dConstE1:             .double 0f1E1dConstME5:            .double 0f1E-5dConstME255:          .double 0f1E-255dConstME127:          .double 0f1E-127dConstME63:           .double 0f1E-63dConstME31:           .double 0f1E-31dConstME15:           .double 0f1E-15dConstME7:            .double 0f1E-7dConstME3:            .double 0f1E-3dConstME1:            .double 0f1E-1dConstE0:             .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 conversion1:                              // 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 final100:        ldp x4,x5,[sp],16           // restaur  registers    ldp x2,x3,[sp],16           // restaur  registers    ldp x1,lr,[sp],16           // restaur registers    ret/***************************************************//*      ROUTINES INCLUDE                           *//***************************************************/.include "../includeARM64.inc"
Difference between +20 and +45 = +25Difference between -45 and +45 = +90Difference between -85 and +90 = +175Difference between -95 and +90 = -175Difference between -45 and +125 = +170Difference between -45 and +145 = -170Difference between +29,4802 and -88,638099 = -118,1Difference between -78,325 and -159 = -80,7108999Difference between -70099,7423381 and +29840,674378 = -139,58328

Action!

Library:Action! Tool Kit
Library:Action! Real Math
INCLUDE "H6:REALMATH.ACT"INT FUNC AngleI(INT a1,a2)  INT r  r=a2-a1  WHILE r>180 DO r==-360 OD  WHILE r<-180 DO r==+360 ODRETURN (r)PROC TestI(INT a1,a2)  INT r  r=AngleI(a1,a2)  PrintF("%I .. %I = %I%E",a1,a2,r)RETURNPROC AngleR(REAL POINTER r1,r2,r)  REAL tmp,r180,rm180,r360  ValR("180",r180)  ValR("-180",rm180)  ValR("360",r360)  RealSub(r2,r1,r)  WHILE RealGreaterOrEqual(r,r180)  DO    RealSub(r,r360,tmp) RealAssign(tmp,r)  OD  WHILE RealGreaterOrEqual(rm180,r)  DO    RealAdd(r,r360,tmp) RealAssign(tmp,r)  ODRETURNPROC TestR(CHAR ARRAY s1,s2)  REAL r1,r2,r  ValR(s1,r1) ValR(s2,r2)  AngleR(r1,r2,r)  PrintR(r1) Print(" .. ") PrintR(r2)  Print(" = ") PrintRE(r)RETURNPROC Main()  Put(125) PutE() ;clear screen  TestI(20,45)  TestI(-45,45)  TestI(-85,90)  TestI(-95,90)  TestI(-45,125)  TestI(-45,145)  TestR("29.4803","-88.6381")  TestR("-78.3251","-159.036")  TestR("-70099.74233810938","29840.67437876723")  TestR("-165313.6666297357","33693.9894517456")  TestR("1174.8380510598456","-154146.66490124757")  TestR("60175.77306795546","42213.07192354373")RETURN
Output:

Screenshot from Atari 8-bit computer

20 .. 45 = 25-45 .. 45 = 90-85 .. 90 = 175-95 .. 90 = -175-45 .. 125 = 170-45 .. 145 = -17029.4803 .. -88.6381 = -118.1184-78.3251 .. -159.036 = -80.7109-70099.7423 .. 29840.6743 = -139.5834-165313.666 .. 33693.9894 = -72.34461174.83805 .. -154146.664 = -161.50260175.773 .. 42213.0719 = 37.2989

Ada

Ada does not provide a built-in mod function for floating point types. This program supplies one.

------------------------------------------------------------------------- Angle difference between two bearings-----------------------------------------------------------------------withAda.Text_IO;useAda.Text_IO;procedureBearing_AnglesistypeRealisdigits8;PackageReal_Iois newAda.Text_IO.Float_IO(Real);useReal_IO;typeAnglesisrecordB1:Real;B2:Real;end record;typeAngle_Arrisarray(Positiverange<>)ofAngles;functionfmod(Left,Right:Real)returnRealisResult:Real;beginResult:=Left-Right*Real'Truncation(Left/Right);returnResult;endfmod;The_Angles:Angle_Arr:=((20.0,45.0),(-45.0,45.0),(-85.0,90.0),(-95.0,90.0),(-14.0,125.0),(29.4803,-88.6381),(-78.3251,-159.036),(-70099.74233810938,29840.67437876723),(-165313.6666297357,33693.9894517456),(1174.8380510598456,-154146.66490124757),(60175.77306795546,42213.07192354373));Diff:Real;beginforAofThe_AnglesloopDiff:=fmod(A.b2-A.b1,360.0);IfDiff<-180.0thenDiff:=Diff+360.0;elsifDiff>180.0thenDiff:=Diff-360.0;endif;Put("Difference between ");Put(Item=>A.B2,Fore=>7,Aft=>4,Exp=>0);Put(" and ");Put(Item=>A.B1,Fore=>7,Aft=>4,Exp=>0);Put(" is ");Put(Item=>Diff,Fore=>4,Aft=>4,Exp=>0);New_Line;endloop;endBearing_Angles;
Output:
Difference between      45.0000 and      20.0000 is   25.0000Difference between      45.0000 and     -45.0000 is   90.0000Difference between      90.0000 and     -85.0000 is  175.0000Difference between      90.0000 and     -95.0000 is -175.0000Difference between     125.0000 and     -14.0000 is  139.0000Difference between     -88.6381 and      29.4803 is -118.1184Difference between    -159.0360 and     -78.3251 is  -80.7109Difference between   29840.6744 and  -70099.7423 is -139.5833Difference between   33693.9895 and -165313.6666 is  -72.3439Difference between -154146.6649 and    1174.8381 is -161.5030Difference between   42213.0719 and   60175.7731 is   37.2989

Agena

Translation of:C++

Tested with Agena 5.0.0 Win32

# Angle difference between two bearingsproc getdiff(b1, b2) is  r := (b2 - b1) symmod 360.0;  if r >= 180.0 then r -:= 360.0 fi;  if r < -180.0 then r +:= 360.0 fi;  return rend;proc printrow(b1, b2) is  printf("%14.6f    %14.6f    %14.6f\n", b1, b2, getdiff(b1, b2))end;scope  print("Input in -180 to +180 range");  print("     Bearing 1         Bearing 2        Difference");  printrow(20.0, 45.0);  printrow(-45.0, 45.0);  printrow(-85.0, 90.0);  printrow(-95.0, 90.0);  printrow(-45.0, 125.0);  printrow(-45.0, 145.0);  printrow(-45.0, 125.0);  printrow(-45.0, 145.0);  printrow(29.4803, -88.6381);  printrow(-78.3251, -159.036);  print();  print("Input in wider range");  print("     Bearing 1         Bearing 2        Difference");  printrow(-70099.74233810938, 29840.67437876723);  printrow(-165313.6666297357, 33693.9894517456);  printrow(1174.8380510598456, -154146.66490124757);  printrow(60175.77306795546, 42213.07192354373)epocs
Output:
Input in -180 to +180 range     Bearing 1         Bearing 2        Difference     20.000000         45.000000         25.000000    -45.000000         45.000000         90.000000    -85.000000         90.000000        175.000000    -95.000000         90.000000       -175.000000    -45.000000        125.000000        170.000000    -45.000000        145.000000       -170.000000    -45.000000        125.000000        170.000000    -45.000000        145.000000       -170.000000     29.480300        -88.638100       -118.118400    -78.325100       -159.036000        -80.710900Input in wider range     Bearing 1         Bearing 2        Difference -70099.742338      29840.674379       -139.583283-165313.666630      33693.989452        -72.343919   1174.838051    -154146.664901       -161.502952  60175.773068      42213.071924         37.298856

ALGOL 68

Translation of:11l
BEGIN # angle difference between 2 bearings - translated from the 11l sample #    PROC wrap = (REAL v, l1, l2 )REAL:         BEGIN            REAL result := v;            WHILE result < l1 DO result +:= 2 * l2 OD;            WHILE result > l2 DO result +:= 2 * l1 OD;            result         END # wrap # ;             PROC get_difference = ( REAL b1, b2 )REAL: wrap( b2 - b1, -180.0, 180.0 );    OP   FMT = ( REAL v )STRING:         BEGIN            STRING result := fixed( ABS v, 0, 3 );            IF result[ LWB result ] = "." THEN "0" +=: result FI;            WHILE result[ UPB result ] = "0" DO result := result[ : UPB result - 1 ] OD;            IF result[ UPB result ] = "." THEN result := result[ : UPB result - 1 ] FI;            IF v < 0 THEN "-" ELSE " " FI + result         END # FMT # ;    print( ( FMT get_difference(  20.0,  45.0 ),       newline ) );    print( ( FMT get_difference( -45.0,  45.0 ),       newline ) );    print( ( FMT get_difference( -85.0,  90.0 ),       newline ) );    print( ( FMT get_difference( -95.0,  90.0 ),       newline ) );    print( ( FMT get_difference( -45.0, 125.0 ),       newline ) );    print( ( FMT get_difference( -45.0, 145.0 ),       newline ) );    print( ( FMT get_difference( -45.0, 125.0 ),       newline ) );    print( ( FMT get_difference( -45.0, 145.0 ),       newline ) );    print( ( FMT get_difference(  29.4803, -88.6381 ), newline ) );    print( ( FMT get_difference( -78.3251, -159.036 ), newline ) );    print( ( newline ) );    print( ( FMT get_difference(  -70099.74233810938,     29840.67437876723 ), newline ) );    print( ( FMT get_difference( -165313.6666297357,      33693.9894517456  ), newline ) );    print( ( FMT get_difference(    1174.8380510598456, -154146.66490124757 ), newline ) );    print( ( FMT get_difference(   60175.77306795546,     42213.07192354373 ), newline ) )END
Output:
 25 90 175-175 170-170 170-170-118.118-80.711-139.583-72.344-161.503 37.299

APL

Returns an angle in (-180,180]; so two opposite bearings have a difference of 180 degrees, which is more natural than -180 degrees.

[0]DB1DIFFB2[1]D180+¯360|180+B2-B1
Output:
      'B1' 'B2' 'DIFFERENCE'⍪(⊂'¯¯¯¯¯¯¯¯¯¯')⍪(⊃B),DIFF/¨B         B1          B2  DIFFERENCE  ¯¯¯¯¯¯¯¯¯¯  ¯¯¯¯¯¯¯¯¯¯  ¯¯¯¯¯¯¯¯¯¯       20          45          25         ¯45          45          90         ¯85          90         175         ¯95          90        ¯175         ¯45         125         170         ¯45         145        ¯170          29.48      ¯88.64     ¯118.12      ¯78.33     ¯159.04      ¯80.71   ¯70099.74    29840.67     ¯139.59  ¯165313.67     3369.99     ¯156.34     1174.84  ¯154146.66     ¯161.5     60175.77    42213.07       37.3        270 DIFF 90.01¯179.99      270 DIFF 90180

AppleScript

ondiff_bearing({b1,b2})setrto(b2-b1)mod360ifr>180thenr-360elseifr<-180thenr+360elserendifenddiff_bearingsettest_bearingsto{{20,45},{-45,45},{-85,90},{-95,90},{-45,125},{-45,145},{29.4803,-88.6381},{-78.3251,-159.036}}setbig_bearingsto{{-7.00997423381094E+4,2.98406743787672E+4},{-1.65313666629736E+5,3.36939894517456E+4},{1174.838051059846,-1.54146664901248E+5},{6.01757730679555E+4,4.22130719235437E+4}}repeatwithbintest_bearings&big_bearingslogdiff_bearing(b)endrepeat
Output:
(*25*)(*90*)(*175*)(*-175*)(*170*)(*-170*)(*-118.1184*)(*-80.7109*)(*-139.5832831234*)(*-72.343918518396*)(*-161.502952307841*)(*37.298855588197*)

ARM Assembly

Works with:as version Raspberry Pi
or android 32 bits with application Termux
/* ARM assembly Raspberry PI or android with termux *//*  program diffAngle.s   */ /* REMARK 1 : this program use routines in a include file    see task Include a file language arm assembly    for the routine affichageMess conversion10    see at end of this program the instruction include *//* for constantes see task include a file in arm assembly *//************************************//* Constantes                       *//************************************/.include "../constantes.inc"/*********************************//* Initialized data              *//*********************************/.dataszCarriageReturn:   .asciz "\n"szMessResult:       .asciz "Difference between @ and @ = @ \n".align 4fB1:            .float 20.0fB2:            .float 45.0fB3:            .float -45.0fB4:            .float -85.0fB5:            .float 90.0fB6:            .float -95.0fB7:            .float 125.0fB8:            .float 145.0fB9:            .float 29.4803 fB10:           .float -88.6381fB11:           .float -78.3251fB12:           .float -159.036fB13:           .float -70099.74233810938fB14:           .float 29840.67437876723/*********************************//* UnInitialized data            *//*********************************/.bss  sZoneConv:           .skip 24/*********************************//*  code section                 *//*********************************/.text.global main main:    ldr r0,iAdrfB1    ldr r1,iAdrfB2    bl testComputeAngle        ldr r0,iAdrfB3    ldr r1,iAdrfB2    bl testComputeAngle        ldr r0,iAdrfB4    ldr r1,iAdrfB5    bl testComputeAngle        ldr r0,iAdrfB6    ldr r1,iAdrfB5    bl testComputeAngle    ldr r0,iAdrfB3    ldr r1,iAdrfB7    bl testComputeAngle        ldr r0,iAdrfB3    ldr r1,iAdrfB8    bl testComputeAngle        ldr r0,iAdrfB9    ldr r1,iAdrfB10    bl testComputeAngle    ldr r0,iAdrfB11    ldr r1,iAdrfB12    bl testComputeAngle    ldr r0,iAdrfB13    ldr r1,iAdrfB14    bl testComputeAngle100:                            @ standard end of the program     mov r0, #0                  @ return code    mov r7, #EXIT               @ request to exit program    svc #0                      @ perform the system calliAdrszCarriageReturn:    .int szCarriageReturniAdrsZoneConv:           .int sZoneConv  iAdrfB1:                .int fB1iAdrfB2:                .int fB2iAdrfB3:                .int fB3iAdrfB4:                .int fB4iAdrfB5:                .int fB5iAdrfB6:                .int fB6iAdrfB7:                .int fB7iAdrfB8:                .int fB8iAdrfB9:                .int fB9iAdrfB10:               .int fB10iAdrfB11:               .int fB11iAdrfB12:               .int fB12iAdrfB13:               .int fB13iAdrfB14:               .int fB14/******************************************************************//*     compute difference and display result                      */ /******************************************************************//* s0 contains bearing 1  *//* s1 contains bearing 2  */testComputeAngle:    push {r1-r3,lr}           @ save  registers     vldr.f32 s0,[r0]    vmov s2,s0    vldr.f32 s1,[r1]    bl computeDiffAngle    vmov s3,s0    vmov s0,s2    ldr r0,iAdrsZoneConv    bl convertirFloat    ldr r0,iAdrszMessResult    ldr r1,iAdrsZoneConv    bl strInsertAtCharInc    mov r3,r0    vmov s0,s1    ldr r0,iAdrsZoneConv    bl convertirFloat    mov r0,r3    ldr r1,iAdrsZoneConv    bl strInsertAtCharInc    mov r3,r0    vmov s0,s3    ldr r0,iAdrsZoneConv    bl convertirFloat    mov r0,r3    ldr r1,iAdrsZoneConv    bl strInsertAtCharInc    bl affichageMess     100:    pop {r1-r3,pc}             @ restaur registersiAdrszMessResult:      .int szMessResult/******************************************************************//*     compute difference of two bearing                                  */ /******************************************************************//* s0 contains bearing 1  *//* s1 contains bearing 2  */computeDiffAngle:    push {r1-r4,lr}           @ save  registers     vpush {s1-s4}    mov r1,#360    mov r4,#0                 @ top positive/negative    vcvt.s32.f32  s4,s0       @ conversion integer    vcvt.f32.s32  s2,s4       @ conversion float    vsub.f32 s2,s0,s2         @ partie décimale    vmov r0,s4                @ partie entière    cmp r0,#0                 @ negative ?    neglt r0,r0               @ yes -> inversion     movlt r4,#1    bl division               @ divide by 360 (r0 dividende r1 divisor r2 quotient r3 remainder)    cmp r4,#0                 @ value negative ?    negne r3,r3               @ inversion remainder    vmov s3,r3    vcvt.f32.s32  s3,s3       @ and conversion float    vadd.f32 s0,s3,s2         @ add decimal part        mov r4,#0                 @ bearing 2    vcvt.s32.f32  s4,s1       @ conversion integer    vcvt.f32.s32  s2,s4       @ conversion float    vsub.f32 s2,s1,s2         @ partie décimale    vmov r0,s4    cmp r0,#0    neglt r0,r0    movlt r4,#1    bl division               @ divide by 360    cmp r4,#0    negne r3,r3               @ negate remainder    vmov s3,r3    vcvt.f32.s32  s3,s3       @ conversion float    vadd.f32 s1,s3,s2          vsub.f32 s0,s1,s0         @ calculate the difference between the 2 values        mov r0,#180    vmov s3,r0    vcvt.f32.s32  s3,s3       @ conversion float 180    vmov s4,r1                @ 360    vcvt.f32.s32  s4,s4       @ conversion float 360        vcmp.f32 s0,#0.0          @ difference is negative ?    vmrs APSR_nzcv, FPSCR     @ flags transfert (do not forget this instruction !!!)    blt 2f                              @ difference is positive    vcmp.f32 s0,s4            @ difference > 360    vmrs APSR_nzcv, FPSCR     @ flags transfert (do not forget this instruction !!!)    vsubgt.f32  s0,s4         @ yes -> difference - 360    vcmp.f32 s0,s3            @ compare difference and 180    vmrs APSR_nzcv, FPSCR     @ flags transfert (do not forget this instruction !!!)    vsubgt.f32 s0,s4,s0       @ > 180 calculate 360 - difference     vneggt.f32 s0,s0          @ and negate    b 100f2:                            @ différence is négative    vneg.f32 s2,s4            @ -360    vcmp.f32 s0,s2            @ compare différence et - 360    vmrs APSR_nzcv, FPSCR     @ flags transfert (do not forget this instruction !!!)    vsubgt.f32  s0,s4         @ sub 360 to différence        vneg.f32 s3,s3            @ -180    vcmp.f32 s0,s3            @ compare difference and -180    vmrs APSR_nzcv, FPSCR     @ flags transfert (do not forget this instruction !!!)    vaddlt.f32 s0,s4,s0       @ calculate 360 + différence100:    vpop {s1-s4}    pop {r1-r4,pc}             @ restaur registers/******************************************************************//*     Conversion Float                                            */ /******************************************************************//* s0  contains Float *//* r0 contains address conversion area  mini 20 charactèrs*//* r0 return result length */convertirFloat:    push {r1-r7,lr}    vpush {s0-s2}    mov r6,r0                 @ save area address    vmov r0,s0    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 end2:     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 100f3:                            @ 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 100f4:    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 zeros5:    ldrb r0,[r6]    cmp r0,#'0'    bne 6f    subs r6,#1    b 5b6:    cmp r0,#','    bne 7f    subs r6,#17:    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,#14:    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 final100:    vpop {s0-s2}    pop {r1-r7,pc}iMaskExposant:            .int 0xFF<<23iConst1:                  .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,#321:    vldr s1,iConstE16    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    blo 2f    vldr s1,iConstE16    vdiv.f32 s0,s0,s1    adds r0,#162:    vldr s1,iConstE8    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    blo 3f    vldr s1,iConstE8    vdiv.f32 s0,s0,s1    adds r0,#83:    vldr s1,iConstE4    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    blo 4f    vldr s1,iConstE4    vdiv.f32 s0,s0,s1    adds r0,#44:    vldr s1,iConstE2    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    blo 5f    vldr s1,iConstE2    vdiv.f32 s0,s0,s1    adds r0,#25:    vldr s1,iConstE1    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    blo 10f    vldr s1,iConstE1    vdiv.f32 s0,s0,s1    adds r0,#110:    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,#3211:    vldr s1,iConstME15    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    bhi 12f    vldr s1,iConstE16    vmul.f32 s0,s0,s1    subs r0,#1612:    vldr s1,iConstME7    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    bhi 13f    vldr s1,iConstE8    vmul.f32 s0,s0,s1    subs r0,#813:    vldr s1,iConstME3    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    bhi 14f    vldr s1,iConstE4    vmul.f32 s0,s0,s1    subs r0,#414:    vldr s1,iConstME1    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    bhi 15f    vldr s1,iConstE2    vmul.f32 s0,s0,s1    subs r0,#215:    vldr s1,iConstE0    vcmp.f32 s0,s1    vmrs APSR_nzcv,FPSCR    bhi 100f    vldr s1,iConstE1    vmul.f32 s0,s0,s1    subs r0,#1100:                       @ fin standard de la fonction    pop {pc}               @ restaur des registres.align 2iConstE7:             .float 0f1E7iConstE32:            .float 0f1E32iConstE16:            .float 0f1E16iConstE8:             .float 0f1E8iConstE4:             .float 0f1E4iConstE2:             .float 0f1E2iConstE1:             .float 0f1E1iConstME5:            .float 0f1E-5iConstME31:           .float 0f1E-31iConstME15:           .float 0f1E-15iConstME7:            .float 0f1E-7iConstME3:            .float 0f1E-3iConstME1:            .float 0f1E-1iConstE0:             .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 decimale1:                             @ 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 final100:        pop {r1-r6,pc}             @ restaur registers   /***************************************************//*      ROUTINES INCLUDE                           *//***************************************************/.include "../affichage.inc"
Difference between +20E0 and +45E0 = +25E0Difference between -45E0 and +45E0 = +90E0Difference between -85E0 and +90E0 = +175E0Difference between -95E0 and +90E0 = -175E0Difference between -45E0 and +125E0 = +170E0Difference between -45E0 and +145E0 = -170E0Difference between +29,48030089E0 and -88,63809964E0 = -118,1184082E0Difference between -78,32510374E0 and -159,03599548E0 = -80,71087648E0Difference between -70099,74218752E0 and +29840,67382809E0 = -139,58398438E0

Arturo

Translation of:Ruby
getDifference:function[b1,b2][r:(b2- b1)%360.0ifr>=180.0->r:r-360.0returnr]print"Input in -180 to +180 range"printgetDifference20.045.0printgetDifferenceneg45.045.0printgetDifferenceneg85.090.0printgetDifferenceneg95.090.0printgetDifferenceneg45.0125.0printgetDifferenceneg45.0145.0printgetDifferenceneg45.0125.0printgetDifferenceneg45.0145.0printgetDifference29.4803neg88.6381printgetDifferenceneg78.3251neg159.036print""print"Input in wider range"printgetDifferenceneg70099.7423381093829840.67437876723printgetDifferenceneg165313.666629735733693.9894517456printgetDifference1174.8380510598456neg154146.66490124757printgetDifference60175.7730679554642213.07192354373
Output:
Input in -180 to +180 range25.090.0175.0-175.0170.0-170.0170.0-170.0-118.1184-80.7109Input in wider range-139.5832831233856-72.34391851868713-161.5029523074045-322.7011444117306

AutoHotkey

Angles:=[[20,45],[-45,45],[-85,90],[-95,90],[-45,125],[-45,145],[29.4803,-88.6381],[-78.3251,-159.036],[-70099.74233810938,29840.67437876723],[-165313.6666297357,33693.9894517456],[1174.8380510598456,-154146.66490124757],[60175.77306795546,42213.07192354373]]fori,setinanglesresult.=set.2" to "set.1" = "Angle_difference_between_two_bearings(set)"`n"MsgBox,262144,,%resultreturnAngle_difference_between_two_bearings(set){return(diff:=Mod(set.2,360)-Mod(set.1,360))>180?diff-360:diff}
Output:
45 to 20 = 2545 to -45 = 9090 to -85 = 17590 to -95 = -175125 to -45 = 170145 to -45 = -170-88.6381 to 29.4803 = -118.118400-159.036 to -78.3251 = -80.71090029840.67437876723 to -70099.74233810938 = 220.41671733693.9894517456 to -165313.6666297357 = -72.343919-154146.66490124757 to 1174.8380510598456 = -161.50295242213.07192354373 to 60175.77306795546 = 37.298856

AWK

# syntax: GAWK -f ANGLE_DIFFERENCE_BETWEEN_TWO_BEARINGS.AWKBEGIN{fmt="%11s %11s %11s\n"while(++i<=11){u=u"-"}printf(fmt,"B1","B2","DIFFERENCE")printf(fmt,u,u,u)main(20,45)main(-45,45)main(-85,90)main(-95,90)main(-45,125)main(-45,145)main(29.4803,-88.6381)main(-78.3251,-159.036)main(-70099.74233810938,29840.67437876723)main(-165313.6666297357,33693.9894517456)main(1174.8380510598456,-154146.66490124757)main(60175.77306795546,42213.07192354373)exit(0)}functionmain(b1,b2){printf("%11.2f %11.2f %11.2f\n",b1,b2,angle_difference(b1,b2))}functionangle_difference(b1,b2,r){r=(b2-b1)%360if(r<-180){r+=360}if(r>=180){r-=360}return(r)}
Output:
         B1          B2  DIFFERENCE----------- ----------- -----------      20.00       45.00       25.00     -45.00       45.00       90.00     -85.00       90.00      175.00     -95.00       90.00     -175.00     -45.00      125.00      170.00     -45.00      145.00     -170.00      29.48      -88.64     -118.12     -78.33     -159.04      -80.71  -70099.74    29840.67     -139.58 -165313.67    33693.99      -72.34    1174.84  -154146.66     -161.50   60175.77    42213.07       37.30

Ballerina

importballerina/io;functionsubtract(floatb1,floatb2)returnsfloat{floatd=(b2-b1)%360.0;ifd<-180.0{d+=360.0;}ifd>=180.0{d-=360.0;}returnd.round(4);}publicfunctionmain(){float[][]pairs=[[20,45],[-45,45],[-85,90],[-95,90],[-45,125],[-45,145],[29.4803,-88.6381],[-78.3251,-159.036],[-70099.74233810938,29840.67437876723],[-165313.6666297357,33693.9894517456],[1174.8380510598456,-154146.66490124757],[60175.77306795546,42213.07192354373]];io:println("Differences (to 4dp) between these bearings:");foreachvarpairinpairs{floatp0=pair[0];floatp1=pair[1];floatdiff=subtract(p0,p1);stringoffset=p0<0.0?" ":"  ";io:println(`${offset}${p0} and ${p1} -> ${diff}`);}}
Output:
Differences (to 4dp) between these bearings:  20.0 and 45.0 -> 25.0 -45.0 and 45.0 -> 90.0 -85.0 and 90.0 -> 175.0 -95.0 and 90.0 -> -175.0 -45.0 and 125.0 -> 170.0 -45.0 and 145.0 -> -170.0  29.4803 and -88.6381 -> -118.1184 -78.3251 and -159.036 -> -80.7109 -70099.74233810938 and 29840.67437876723 -> -139.5833 -165313.6666297357 and 33693.9894517456 -> -72.3439  1174.8380510598456 and -154146.66490124757 -> -161.503  60175.77306795546 and 42213.07192354373 -> 37.2989

BASIC

ANSI BASIC

Translation of:C++
Works with:Decimal BASIC
100REM Angle difference between two bearings110DECLAREEXTERNALFUNCTIONGetDiff120REM130SUBPrintRow(B1,B2)140PRINTUSING"#######.######    #######.######    #######.######":B1,B2,GetDiff(B1,B2)150ENDSUB160REM170print"Input in -180 to +180 range"180PRINT"     Bearing 1         Bearing 2        Difference"190CALLPrintRow(20.0,45.0)200CALLPrintRow(-45.0,45.0)210CALLPrintRow(-85.0,90.0)220CALLPrintRow(-95.0,90.0)230CALLPrintRow(-45.0,125.0)240CALLPrintRow(-45.0,145.0)250CALLPrintRow(-45.0,125.0)260CALLPrintRow(-45.0,145.0)270CALLPrintRow(29.4803,-88.6381)280CALLPrintRow(-78.3251,-159.036)290PRINT300PRINT"Input in wider range"310PRINT"     Bearing 1         Bearing 2        Difference"320CALLPrintRow(-70099.74233810938,29840.67437876723)330CALLPrintRow(-165313.6666297357,33693.9894517456)340CALLPrintRow(1174.8380510598456,-154146.66490124757)350CALLPrintRow(60175.77306795546,42213.07192354373)360END370REM380EXTERNALFUNCTIONGetDiff(B1,B2)390LETR=MOD(B2-B1,360.0)400IFR>=180.0THENLETR=R-360.0410LETGetDiff=R420ENDFUNCTION
Output:
Input in -180 to +180 range     Bearing 1         Bearing 2        Difference     20.000000         45.000000         25.000000    -45.000000         45.000000         90.000000    -85.000000         90.000000        175.000000    -95.000000         90.000000       -175.000000    -45.000000        125.000000        170.000000    -45.000000        145.000000       -170.000000    -45.000000        125.000000        170.000000    -45.000000        145.000000       -170.000000     29.480300        -88.638100       -118.118400    -78.325100       -159.036000        -80.710900Input in wider range     Bearing 1         Bearing 2        Difference -70099.742338      29840.674379       -139.583283-165313.666630      33693.989452        -72.343919   1174.838051    -154146.664901       -161.502952  60175.773068      42213.071924         37.298856

BASIC256

Translation of:Python
# Rosetta Code problem: http://rosettacode.org/wiki/Angle_difference_between_two_bearings# by Jjuanhdez, 06/2022print "Input in -180 to +180 range:"call getDifference(20.0, 45.0)call getDifference(-45.0, 45.0)call getDifference(-85.0, 90.0)call getDifference(-95.0, 90.0)call getDifference(-45.0, 125.0)call getDifference(-45.0, 145.0)call getDifference(-45.0, 125.0)call getDifference(-45.0, 145.0)call getDifference(29.4803, -88.6381)call getDifference(-78.3251, -159.036)printprint "Input in wider range:"call getDifference(-70099.74233810938, 29840.67437876723)call getDifference(-165313.6666297357, 33693.9894517456)call getDifference(1174.8380510598456, -154146.66490124757)endsubroutine getDifference(b1, b2)r = (b2 - b1) mod 360if r >= 180.0 then r -= 360.0print ljust(b1,16); ljust(b2,16); ljust(r,12)end subroutine

Chipmunk Basic

Translation of:Python
Works with:Chipmunk Basic version 3.6.4
Works with:QBasic
100cls110subgetdifference(b1,b2)120r=(b2-b1)mod360130ifr>=180thenr=r-360140printusing"#######.######";b1;150printusing"    #######.######";b2;160printusing"    #######.######";r170endsub180print"Input in -180 to +180 range:"190print"     b1                b2               difference"200print" -------------------------------------------------"210getdifference(20,45)220getdifference(-45,45)230getdifference(-85,90)240getdifference(-95,90)250getdifference(-45,125)260getdifference(-45,145)270getdifference(-45,125)280getdifference(-45,145)290getdifference(29.4803,-88.6381)300getdifference(-78.3251,-159.036)310getdifference(-70099.742338,29840.674379)320getdifference(-165313.66663,33693.989452)330getdifference(1174.838051,-154146.664901)340print350print"Input in wider range:"360print"     b1                b2               difference"370print" -------------------------------------------------"380getdifference(-70099.742338,29840.674379)390getdifference(-165313.66663,33693.989452)400getdifference(1174.838051,-154146.664901)410getdifference(60175.773068,42213.071924)
Output:
Input in -180 to +180 range:     b1                b2               difference -------------------------------------------------     20.000000         45.000000         25.000000    -45.000000         45.000000         90.000000    -85.000000         90.000000        175.000000    -95.000000         90.000000       -175.000000    -45.000000        125.000000        170.000000    -45.000000        145.000000       -170.000000    -45.000000        125.000000        170.000000    -45.000000        145.000000       -170.000000     29.480300        -88.638100       -118.000000    -78.325100       -159.036000        -80.000000 -70099.742338      29840.674379       -140.000000-165313.666630      33693.989452        -73.000000   1174.838051    -154146.664901       -161.000000Input in wider range:     b1                b2               difference ------------------------------------------------- -70099.742338      29840.674379       -140.000000-165313.666630      33693.989452        -73.000000   1174.838051    -154146.664901       -161.000000  60175.773068      42213.071924       -322.000000

Craft Basic

precision4defines1=0,s2=0dimb1[20,-45,-85,-95,-45,-45,29.4803,-78.3251]dimb2[45,45,90,90,125,145,-88.6381,-159.036]arraysizes1,b1arraysizes2,b2ifs1=s2thenfori=0tos1-1letr=(b2[i]-b1[i])%360ifr>=180thenletr=r-360endifprint"bearing 1: ",b1[i]," bearing 2: ",b2[i]," difference: ",rnextiendif
Output:
bearing 1: 20 bearing 2: 45 difference: 25bearing 1: -45 bearing 2: 45 difference: 90bearing 1: -85 bearing 2: 90 difference: 175bearing 1: -95 bearing 2: 90 difference: -175bearing 1: -45 bearing 2: 125 difference: 170bearing 1: -45 bearing 2: 145 difference: -170bearing 1: 29.4803 bearing 2: -88.6381 difference: -118bearing 1: -78.3251 bearing 2: -159.0360 difference: -80

FreeBASIC

' version 28-01-2019' compile with: fbc -s console#Include"string.bi"Functionfrmt(numAsDouble)AsStringDimAsStringtemp=Format(num,"#######.#############")DimAsIntegeri=Len(temp)-1Iftemp[i]=Asc(".")Thentemp[i]=32IfInStr(temp,".")=0ThenReturnRight(Space(10)+temp,9)+Space(13)EndIftemp=Space(10)+temp+Space(13)ReturnMid(temp,InStr(temp,".")-8,22)EndFunction' ------=< MAIN >=------DimAsDoubleb1,b2,bb1,bb2,diffPrintPrint"      b1                    b2                    difference"Print" -----------------------------------------------------------"DoReadb1,b2Ifb1=0Andb2=0ThenExitDodiff=b2-b1diff=diff-Int(diff/360)*360Ifdiff>180Thendiff-=360Printfrmt(b1);frmt(b2);frmt(diff)LoopData20,45,-45,45,-85,90Data-95,90,-45,125,-45,145Data29.4803,-88.6381,-78.3251,-159.036Data-70099.74233810938,29840.67437876723Data-165313.6666297357,33693.9894517456Data1174.8380510598456,-154146.66490124757Data60175.77306795546,42213.07192354373' empty keyboard bufferWhileInKey<>"":WendPrint:Print"hit any key to end program"SleepEnd
Output:
      b1                    b2                    difference -----------------------------------------------------------      20                    45                    25     -45                    45                    90     -85                    90                   175     -95                    90                  -175     -45                   125                   170     -45                   145                  -170      29.4803              -88.6381             -118.1184     -78.3251             -159.036               -80.7109  -70099.7423381093831   29840.6743787672312    -139.5832831233856 -165313.6666297357006   33693.9894517455978     -72.3439185186871    1174.8380510598461 -154146.6649012475973    -161.5029523074336   60175.7730679554588   42213.0719235437282      37.2988555882694

IS-BASIC

100INPUTPROMPT"1. angle: ":A1110INPUTPROMPT"2. angle: ":A2120LETB=MOD(A2-A1,360)130IFB>180THENLETB=B-360140IFB<-180THENLETB=B+360150PRINT"Difference: ";B

PureBasic

Translation of:Python
Procedure.fgetDifference(b1.f,b2.f)r.f=Mod((b2-b1),360)Ifr>=180:r-360EndIfPrintN(StrF(b1)+#TAB$+StrF(b2)+#TAB$+StrF(r));EndProcedureIfOpenConsole()PrintN("Input in -180 to +180 range:")getDifference(20.0,45.0)getDifference(-45.0,45.0)getDifference(-85.0,90.0)getDifference(-95.0,90.0)getDifference(-45.0,125.0)getDifference(-45.0,145.0)getDifference(-45.0,125.0)getDifference(-45.0,145.0)getDifference(29.4803,-88.6381)getDifference(-78.3251,-159.036)PrintN(#CRLF$+"Input in wider range:")getDifference(-70099.74233810938,29840.67437876723)getDifference(-165313.6666297357,33693.9894517456)getDifference(1174.8380510598456,-154146.66490124757)getDifference(60175.77306795546,42213.07192354373)Repeat:UntilInkey()<>""EndIf

QBasic /QuickBASIC

Works with:QBasic version 1.1
Works with:QuickBasic version 4.5
SUBgetDifference(b1!,b2!)r!=(b2-b1)MOD360!IFr>=180!THENr=r-360!PRINTUSING"#######.######    #######.######    #######.######";b1;b2;rENDSUBPRINT"     Bearing 1         Bearing 2        Difference"CALLgetDifference(20!,45!)CALLgetDifference(-45!,45!)CALLgetDifference(-85!,90!)CALLgetDifference(-95!,90!)CALLgetDifference(-45!,125!)CALLgetDifference(-45!,145!)CALLgetDifference(-45!,125!)CALLgetDifference(-45!,145!)CALLgetDifference(29.4803,-88.6381)CALLgetDifference(-78.3251,-159.036)CALLgetDifference(-70099.74233810938#,29840.67437876723#)CALLgetDifference(-165313.6666297357#,33693.9894517456#)CALLgetDifference(1174.838051059846#,-154146.6649012476#)

Run BASIC

sub getDifference b1, b2    r = (b2 - b1) mod 360    if r >= 180 then r = r - 360    print rend subprint "Input in -180 to +180 range:"call getDifference  20, 45 call getDifference -45, 45 call getDifference -85, 90call getDifference -95, 90call getDifference -45, 125call getDifference -45, 145call getDifference -45, 125call getDifference -45, 145call getDifference  29.4803, -88.6381call getDifference -78.3251, -159.036print "Input in wider range:"call getDifference -70099.74233810938, 29840.67437876723call getDifference -165313.6666297357, 33693.9894517456call getDifference 1174.8380510598456, -154146.66490124757

True BASIC

SUBgetdifference(b1,b2)LETr=REMAINDER(b2-b1,360.0)IFr>=180.0THENLETr=r-360.0PRINTUSING"#######.######    #######.######    #######.######":b1,b2,rENDSUBPRINT"     Bearing 1         Bearing 2        Difference"CALLgetdifference(20.0,45.0)CALLgetdifference(-45.0,45.0)CALLgetdifference(-85.0,90.0)CALLgetdifference(-95.0,90.0)CALLgetdifference(-45.0,125.0)CALLgetdifference(-45.0,145.0)CALLgetdifference(-45.0,125.0)CALLgetdifference(-45.0,145.0)CALLgetdifference(29.4803,-88.6381)CALLgetdifference(-78.3251,-159.036)CALLgetdifference(-70099.74233810938,29840.67437876723)CALLgetdifference(-165313.6666297357,33693.9894517456)CALLgetdifference(1174.8380510598456,-154146.66490124757)END

VBA

Translation of:Phix
PrivateFunctiontx(aAsVariant)AsStringDimsAsStrings=CStr(Format(a,"0.######"))IfRight(s,1)=","Thens=Mid(s,1,Len(s)-1)&"       "Elsei=InStr(1,s,",")s=s&String$(6-Len(s)+i," ")EndIftx=sEndFunctionPrivateSubtest(b1AsVariant,b2AsVariant)DimdiffAsVariantdiff=(b2-b1)-((b2-b1)\360)*360diff=diff-IIf(diff>180,360,0)diff=diff+IIf(diff<-180,360,0)Debug.PrintFormat(tx(b1),"@@@@@@@@@@@@@@@@");Format(tx(b2),"@@@@@@@@@@@@@@@@@");Format(tx(diff),"@@@@@@@@@@@@@@@@@")EndSubPublicSubangle_difference()Debug.Print"       b1               b2             diff"Debug.Print"---------------- ---------------- ----------------"test20,45test-45,45test-85,90test-95,90test-45,125test-45,145test29.4803,-88.6381test-78.3251,-159.036test-70099.7423381094,29840.6743787672test-165313.666629736,33693.9894517456test1174.83805105985,-154146.664901248test60175.7730679555,42213.0719235437EndSub
Output:
       b1               b2             diff---------------- ---------------- ----------------       20               45               25             -45               45               90             -85               90              175             -95               90             -175             -45              125              170             -45              145             -170              29,4803         -88,6381        -118,1184        -78,3251        -159,036          -80,7109     -70099,742338     29840,674379      -139,583283  -165313,66663      33693,989452       -72,343919     1174,838051   -154146,664901      -161,502952    60175,773068     42213,071924        37,298856

Visual Basic .NET

Translation of:C#
ModuleModule1FunctionDelta_Bearing(b1AsDecimal,b2AsDecimal)AsDecimalDimdAsDecimal=0' Convert bearing to W.C.BWhileb1<0b1+=360EndWhileWhileb1>360b1-=360EndWhileWhileb2<0b2+=360EndWhileWhileb2>0b2-=360EndWhile' Calculate delta bearingd=(b2-b1)Mod360' Convert result to Q.BIfd>180Thend-=360ElseIfd<-180Thend+=360EndIfReturndEndFunctionSubMain()' Calculate standard test casesConsole.WriteLine(Delta_Bearing(20,45))Console.WriteLine(Delta_Bearing(-45,45))Console.WriteLine(Delta_Bearing(-85,90))Console.WriteLine(Delta_Bearing(-95,90))Console.WriteLine(Delta_Bearing(-45,125))Console.WriteLine(Delta_Bearing(-45,145))Console.WriteLine(Delta_Bearing(29.4803,-88.6381))Console.WriteLine(Delta_Bearing(-78.3251,-159.036))' Calculate optional test casesConsole.WriteLine(Delta_Bearing(-70099.742338109383,29840.674378767231))Console.WriteLine(Delta_Bearing(-165313.6666297357,33693.9894517456))Console.WriteLine(Delta_Bearing(1174.8380510598456,-154146.66490124757))Console.WriteLine(Delta_Bearing(60175.773067955459,42213.071923543728))EndSubEndModule
Output:
2590175-175170-170-118.1184-80.7109-139.5832831234-72.3439185184-161.5029523078537.2988555882

Yabasic

Translation of:Python
//RosettaCodeproblem:http://rosettacode.org/wiki/Angle_difference_between_two_bearings//byJjuanhdez,06/2022print"Input in -180 to +180 range:"getDifference(20.0,45.0)getDifference(-45.0,45.0)getDifference(-85.0,90.0)getDifference(-95.0,90.0)getDifference(-45.0,125.0)getDifference(-45.0,145.0)getDifference(-45.0,125.0)getDifference(-45.0,145.0)getDifference(29.4803,-88.6381)getDifference(-78.3251,-159.036)print"\nInput in wider range:"getDifference(-70099.74233810938,29840.67437876723)getDifference(-165313.6666297357,33693.9894517456)getDifference(1174.8380510598456,-154146.66490124757)endsubgetDifference(b1,b2)r=mod((b2-b1),360.0)ifr>=180.0r=r-360.0printrendsub

Befunge

012pv12345678>&:v>859**%:459**1-`#v_>12g!:12p#v_\-:459**1-`#v_>.>>0`#^_8v>859**-^>859**-^^:+**95<>^

The labelled points are:1. Initialise write/not write and read input,2. Put in the range 0-360 if negative,3. Likewise if positive,4. Put in range -180 - 180,5. Check if write/not write step,6. If write find difference,7. Scale to -180 - 180,8. Write out and onto next pair.

Unfortunately, due to the lack of floating-point arithmetic in befunge, it is impossible to do the full challenge, however, given the integer truncations of these values it works.

Input:

20 45-45 45-85 90-95 90-45 125-45 14529 -88-78 -159-70099 29840-165313 336931174 -15414660175 42213
Output:
25 90 175 -175 170 -170 -117 -81 -141 -74 -160 38

BQN

Adiff180-360|180+-tests[2045,¯4545,¯8590,¯9590,¯45125,¯4514599279,29.4803¯88.6381,¯78.3251¯159.036¯70099.7423381093829840.67437876723¯165313.666629735733693.98945174561174.8380510598456¯154146.6649012475760175.7730679554642213.07192354373]Round+0.5(1e3×)Round(Adiff´)˘tests
Output:
┌─╵          20          45       25          ¯45          45       90          ¯85          90      175          ¯95          90     ¯175          ¯45         125      170          ¯45         145     ¯170           99         279      180        29.48     ¯88.638 ¯118.118      ¯78.325    ¯159.036  ¯80.711   ¯70099.742   29840.674 ¯139.583  ¯165313.667   33693.989  ¯72.344     1174.838 ¯154146.665 ¯161.503    60175.773   42213.072   37.299                                   ┘

C

This implementation either reads two bearings from the console or a file containing a list of bearings. Usage printed on incorrect invocation.

#include<stdlib.h>#include<stdio.h>#include<math.h>voidprocessFile(char*name){inti,records;doublediff,b1,b2;FILE*fp=fopen(name,"r");fscanf(fp,"%d\n",&records);for(i=0;i<records;i++){fscanf(fp,"%lf%lf",&b1,&b2);diff=fmod(b2-b1,360.0);printf("\nDifference between b2(%lf) and b1(%lf) is %lf",b2,b1,(diff<-180)?diff+360:((diff>=180)?diff-360:diff));}fclose(fp);}intmain(intargC,char*argV[]){doublediff;if(argC<2)printf("Usage : %s <bearings separated by a space OR full file name which contains the bearing list>",argV[0]);elseif(argC==2)processFile(argV[1]);else{diff=fmod(atof(argV[2])-atof(argV[1]),360.0);printf("Difference between b2(%s) and b1(%s) is %lf",argV[2],argV[1],(diff<-180)?diff+360:((diff>=180)?diff-360:diff));}return0;}

Invocation and output for two bearings :

C:\rosettaCode>bearingDiff.exe 29.4803 -88.6381Difference between b2(-88.6381) and b1(29.4803) is -118.118400

File format for bearing list :

<Number of records><Each record consisting of two bearings separated by a space>

Input file :

1220 45-45 45-85 90-95 90-45 125-45 14529.4803 -88.6381-78.3251 -159.036-70099.74233810938 29840.67437876723-165313.6666297357 33693.98945174561174.8380510598456 -154146.6649012475760175.77306795546 42213.07192354373

Invocation and output for above bearing list file :

C:\rosettaCode>bearingDiff.exe bearingList.txtDifference between b2(45.000000) and b1(20.000000) is 25.000000Difference between b2(45.000000) and b1(-45.000000) is 90.000000Difference between b2(90.000000) and b1(-85.000000) is 175.000000Difference between b2(90.000000) and b1(-95.000000) is -175.000000Difference between b2(125.000000) and b1(-45.000000) is 170.000000Difference between b2(145.000000) and b1(-45.000000) is -170.000000Difference between b2(-88.638100) and b1(29.480300) is -118.118400Difference between b2(-159.036000) and b1(-78.325100) is -80.710900Difference between b2(29840.674379) and b1(-70099.742338) is -139.583283Difference between b2(33693.989452) and b1(-165313.666630) is -72.343919Difference between b2(-154146.664901) and b1(1174.838051) is -161.502952Difference between b2(42213.071924) and b1(60175.773068) is 37.298856

C#

usingSystem;namespaceAngle_difference_between_two_bearings{classProgram{publicstaticvoidMain(string[]args){Console.WriteLine();Console.WriteLine("Hello World!");Console.WriteLine();// Calculate standard test casesConsole.WriteLine(Delta_Bearing(20M,45));Console.WriteLine(Delta_Bearing(-45M,45M));Console.WriteLine(Delta_Bearing(-85M,90M));Console.WriteLine(Delta_Bearing(-95M,90M));Console.WriteLine(Delta_Bearing(-45M,125M));Console.WriteLine(Delta_Bearing(-45M,145M));Console.WriteLine(Delta_Bearing(29.4803M,-88.6381M));Console.WriteLine(Delta_Bearing(-78.3251M,-159.036M));// Calculate optional test casesConsole.WriteLine(Delta_Bearing(-70099.74233810938M,29840.67437876723M));Console.WriteLine(Delta_Bearing(-165313.6666297357M,33693.9894517456M));Console.WriteLine(Delta_Bearing(1174.8380510598456M,-154146.66490124757M));Console.WriteLine(Delta_Bearing(60175.77306795546M,42213.07192354373M));Console.WriteLine();Console.Write("Press any key to continue . . . ");Console.ReadKey(true);}staticdecimalDelta_Bearing(decimalb1,decimalb2){/* * Optimal solution *decimal d = 0;d = (b2-b1)%360;if(d>180)d -= 360;else if(d<-180)d += 360;return d; * * *///////decimald=0;// Convert bearing to W.C.Bif(b1<0)b1+=360;if(b2<0)b2+=360;///Calculate delta bearing//and//Convert result value to Q.B.d=(b2-b1)%360;if(d>180)d-=360;elseif(d<-180)d+=360;returnd;//////}}}
Output:
Hello World!2590175-175170-170-118,1184-80,7109-139,58328312339-72,3439185187-161,502952307415637,29885558827Press any key to continue . . .

C++

#include<cmath>#include<iostream>usingnamespacestd;doublegetDifference(doubleb1,doubleb2){doubler=fmod(b2-b1,360.0);if(r<-180.0)r+=360.0;if(r>=180.0)r-=360.0;returnr;}inlinevoidprintRow(doubleb1,doubleb2){cout<<getDifference(b1,b2)<<endl;}intmain(){cout<<"Input in -180 to +180 range"<<endl;printRow(20.0,45.0);printRow(-45.0,45.0);printRow(-85.0,90.0);printRow(-95.0,90.0);printRow(-45.0,125.0);printRow(-45.0,145.0);printRow(-45.0,125.0);printRow(-45.0,145.0);printRow(29.4803,-88.6381);printRow(-78.3251,-159.036);cout<<endl<<"Input in wider range"<<endl;printRow(-70099.74233810938,29840.67437876723);printRow(-165313.6666297357,33693.9894517456);printRow(1174.8380510598456,-154146.66490124757);printRow(60175.77306795546,42213.07192354373);return0;}
Output:
Input in -180 to +180 range2590175-175170-170170-170-118.118-80.7109Input in wider range-139.583-72.3439-161.50337.2989

Clojure

(defnangle-difference[ab](let[r(mod(-ba)360)](if(>=r180)(-r360)r)))(angle-difference2045); 25(angle-difference-4545); 90(angle-difference-8590); 175(angle-difference-9590); -175(angle-difference-70099.7429840.67); -139.59

COBOL

      ******************************************************************      * COBOL solution to Angle difference challange      * The program was run on OpenCobolIDE      * I chose to read the input data from a .txt file that I      *    created on my PC rather than to hard code it into the      *    program or enter it as the program was executing.      ******************************************************************IDENTIFICATIONDIVISION.PROGRAM-ID.ANGLE-DIFFERENCE.ENVIRONMENTDIVISION.INPUT-OUTPUTSECTION.FILE-CONTROL.SELECTIN-FILEASSIGNTO'C:\Both\Rosetta\Angle_diff.txt'ORGANIZATIONISLINESEQUENTIAL.DATADIVISION.FILESECTION.FDIN-FILE.01IN-RECORD.05ALPHA-BEARING-1PIC X(20).05FILLERPIC X.05ALPHA-BEARING-2PIC X(20).WORKING-STORAGESECTION.01SWITCHES.05EOF-SWITCHPIC XVALUE'N'.01COUNTERS.05REC-CTRPIC 9(3)VALUE0.01WS-ALPHA-BEARING.05WS-AB-SIGNPIC X.88WS-AB-NEGATIVEVALUE"-".05WS-AB-INTEGER-PARTPIC X(6).05WS-AB-DEC-POINTPIC X.05WS-AB-DECIMAL-PARTPIC X(12).01WS-BEARING-1PIC S9(6)V9(12).01WS-BEARING-2PIC S9(6)V9(12).01WS-BEARINGPIC S9(6)V9(12).01FILLERREDEFINESWS-BEARING.05WSB-INTEGER-PARTPIC X(6).05WSB-DECIMAL-PARTPIC X9(12).77WS-RESULTPIC S9(6)V9(12).77WS-RESULT-POSPIC 9(6)V9(12).77WS-INTEGER-PARTPIC 9(6).77WS-DECIMAL-PARTPIC V9(12).77WS-RESULT-OUTPIC ------9.9999.PROCEDUREDIVISION.000-MAIN.PERFORM100-INITIALIZE.PERFORM200-PROCESS-RECORDUNTILEOF-SWITCH='Y'.PERFORM300-TERMINATE.STOPRUN.100-INITIALIZE.OPENINPUTIN-FILE.PERFORM150-READ-RECORD.150-READ-RECORD.READIN-FILEATENDMOVE'Y'TOEOF-SWITCHNOTATENDCOMPUTEREC-CTR=REC-CTR+1END-READ.200-PROCESS-RECORD.MOVEALPHA-BEARING-1TOWS-ALPHA-BEARING.PERFORM250-CONVERT-DATA.MOVEWS-BEARINGTOWS-BEARING-1.MOVEALPHA-BEARING-2TOWS-ALPHA-BEARING.PERFORM250-CONVERT-DATA.MOVEWS-BEARINGTOWS-BEARING-2.COMPUTEWS-RESULT=WS-BEARING-2-WS-BEARING-1.MOVEWS-RESULTTOWS-RESULT-POS.MOVEWS-RESULT-POSTOWS-INTEGER-PART.COMPUTEWS-DECIMAL-PART=WS-RESULT-POS-WS-INTEGER-PART.COMPUTEWS-INTEGER-PART=FUNCTIONMOD(WS-INTEGER-PART360).IFWS-RESULT>0COMPUTEWS-RESULT=WS-INTEGER-PART+WS-DECIMAL-PARTELSECOMPUTEWS-RESULT=(WS-INTEGER-PART+WS-DECIMAL-PART)*-1END-IF.IFWS-RESULT<-180COMPUTEWS-RESULT=WS-RESULT+360.IFWS-RESULT>180COMPUTEWS-RESULT=WS-RESULT-360.COMPUTEWS-RESULT-OUTROUNDED=WS-RESULT.DISPLAYREC-CTR' 'WS-RESULT-OUT.PERFORM150-READ-RECORD.250-CONVERT-DATA.MOVEWS-AB-INTEGER-PARTTOWSB-INTEGER-PART.MOVEWS-AB-DECIMAL-PARTTOWSB-DECIMAL-PART.IFWS-AB-NEGATIVESUBTRACTWS-BEARINGFROMZEROGIVINGWS-BEARINGEND-IF.300-TERMINATE.DISPLAY'RECORDS PROCESSED: 'REC-CTR.CLOSEIN-FILE.      ******************************************************************      *    INPUT FILE ('Angle_diff.txt' stored on my PC at:      *            'C:\Both\Rosetta\Angle_diff.txt'      ******************************************************************      *     +000020.000000000000 +000045.000000000000      *     -000045.000000000000 +000045.000000000000      *     -000085.000000000000 +000090.000000000000      *     -000095.000000000000 +000090.000000000000      *     -000045.000000000000 +000125.000000000000      *     -000045.000000000000 +000145.000000000000      *     +000029.480300000000 -000088.638100000000      *     -000078.325100000000 -000159.036000000000      *     -070099.742338109380 +029840.674378767230      *     -165313.666629735700 +033693.989451745600      *     +001174.838051059846 -154146.664901247570      *     +060175.773067955460 +042213.071923543730      ******************************************************************      *    OUTPUT:      ******************************************************************      *     001      25.0000      *     002      90.0000      *     003     175.0000      *     004    -175.0000      *     005     170.0000      *     006    -170.0000      *     007    -118.1184      *     008     -80.7109      *     009    -139.5833      *     010     -72.3439      *     011    -161.5030      *     012      37.2989      ******************************************************************

Common Lisp

(defun angle-difference (b1 b2)   (let ((diff (mod (- b2 b1) 360)))     (if (< diff -180) (incf diff 360) (if (> diff 180)     (decf diff 360)     diff))))
Output:
CL-USER> (angle-difference 20 45)25CL-USER> (angle-difference -45 45)90CL-USER> (angle-difference -85 90)175CL-USER> (angle-difference -95 90)-175CL-USER> (angle-difference -70099.74 29840.67)-139.58594

D

Translation of:Java
importstd.stdio;doublegetDifference(doubleb1,doubleb2){doubler=(b2-b1)%360.0;if(r<-180.0){r+=360.0;}if(r>=180.0){r-=360.0;}returnr;}voidmain(){writeln("Input in -180 to +180 range");writeln(getDifference(20.0,45.0));writeln(getDifference(-45.0,45.0));writeln(getDifference(-85.0,90.0));writeln(getDifference(-95.0,90.0));writeln(getDifference(-45.0,125.0));writeln(getDifference(-45.0,145.0));writeln(getDifference(-45.0,125.0));writeln(getDifference(-45.0,145.0));writeln(getDifference(29.4803,-88.6381));writeln(getDifference(-78.3251,-159.036));writeln("Input in wider range");writeln(getDifference(-70099.74233810938,29840.67437876723));writeln(getDifference(-165313.6666297357,33693.9894517456));writeln(getDifference(1174.8380510598456,-154146.66490124757));writeln(getDifference(60175.77306795546,42213.07192354373));}
Output:
Input in -180 to +180 range2590175-175170-170170-170-118.118-80.7109Input in wider range-139.583-72.3439-161.50337.2989

Delphi

See#Pascal.

EasyLang

Translation of:AWK
func angdiff a b .   r = (b - a) mod 360   if r < -180      r += 360   elif r >= 180      r -= 360   .   return r.proc pd a b .   print b & " " & a & " -> " & angdiff a b.pd 20 45pd -45 45pd -85 90pd -95 90pd -45 125pd -45 145pd 29.4803 -88.6381pd -78.3251 -159.036pd -70099.74233810938 29840.67437876723pd -165313.6666297357 33693.9894517456pd 1174.8380510598456 -154146.66490124757pd 60175.77306795546 42213.07192354373
Output:
45 20 -> 2545 -45 -> 9090 -85 -> 17590 -95 -> -175125 -45 -> 170145 -45 -> -170-88.64 29.48 -> -118.12-159.04 -78.33 -> -80.7129840.67 -70099.74 -> -139.5833693.99 -165313.67 -> -72.34-154146.66 1174.84 -> -161.5042213.07 60175.77 -> 37.30

Erlang

The real number calculations are done using integer arithmetic to better handlerounding errors. Erlang uses extended precision integers so there will be no overflow. The module is tested by running the test function, which in turn matches expected resultswith the result of function call.

-module(bearings).%% API-export([angle_sub_degrees/2,test/0]).-define(RealAngleMultiplier,16#10000000000).-define(DegreesPerTurn,360).-define(Precision,9).%%%===================================================================%%% API%%%===================================================================%%--------------------------------------------------------------------%% @doc%% @spec%% @end%%--------------------------------------------------------------------%%angle_sub_degrees(B1,B2)whenis_integer(B1),is_integer(B2)->angle_sub(B2-B1,?DegreesPerTurn);angle_sub_degrees(B1,B2)->NewB1=trunc(B1*?RealAngleMultiplier),NewB2=trunc(B2*?RealAngleMultiplier),round(angle_sub(NewB2-NewB1,?DegreesPerTurn*?RealAngleMultiplier)/?RealAngleMultiplier,?Precision).%%%===================================================================%%% Internal functions%%%===================================================================%% delta normalises the angle difference.  Consider a turn from 350 degrees%% to 20 degrees.  Subtraction results in 330 degress.  This is equivalent of%% a turn in the other direction of 30 degrees, thus 330 degrees is equal%% to -30 degrees.angle_sub(Value,TurnSize)->NormalisedValue=ValueremTurnSize,minimise_angle(NormalisedValue,TurnSize).% X rem Turn result in 0..Turn for X > 0 and -Turn..0 for X < 0% specification requires -Turn/2 < X < Turn/2.  This is achieved% by adding or removing a turn as required.% bsr 1 divides an integer by 2minimise_angle(Angle,Turn)whenAngle+(Turnbsr1)<0->Angle+Turn;minimise_angle(Angle,Turn)whenAngle-(Turnbsr1)>0->Angle-Turn;minimise_angle(Angle,_)->Angle.round(Number,Precision)->P=math:pow(10,Precision),round(Number*P)/P.test()->25=angle_sub_degrees(20,45),90=angle_sub_degrees(-45,45),175=angle_sub_degrees(-85,90),-175=angle_sub_degrees(-95,90),170=angle_sub_degrees(-45,125),-170=angle_sub_degrees(-45,145),-118.1184=angle_sub_degrees(29.4803,-88.6381),-139.583283124=angle_sub_degrees(-70099.742338109,29840.674378767),-72.343918514=angle_sub_degrees(-165313.66662974,33693.989451746),-161.50295231=angle_sub_degrees(1174.8380510598,-154146.66490125),37.298855589=angle_sub_degrees(60175.773067955,42213.071923544),passed.

Excel

LAMBDA

Binding the names ANGLEBETWEENBEARINGS and BEARINGDELTA to the following lambda expressions in the Name Manager of the Excel WorkBook:

(SeeLAMBDA: The ultimate Excel worksheet function)

Works with:Office 365 betas 2021
ANGLEBETWEENBEARINGS=LAMBDA(ab,DEGREES(BEARINGDELTA(RADIANS(ab))))BEARINGDELTA=LAMBDA(ab,LET(sinab,SIN(ab),cosab,COS(ab),ax,INDEX(sinab,1),bx,INDEX(sinab,2),ay,INDEX(cosab,1),by,INDEX(cosab,2),rem,"Sign * dot product",IF(0<((ay*bx)-(by*ax)),1,-1)*ACOS((ax*bx)+(ay*by))))

Using an Excel custom number format to display the degree symbol°

Output:
fx=ANGLEBETWEENBEARINGS(D2#)
ABCDE
1Differenceb1b2
225.00°2045
390.00°-4545
4175.00°-8590
5-175.00°-9590
6170.00°-45125
7-170.00°-45145
8-118.12°29.4803-88.6381
9-80.71°-78.3251-159.0360
10
11-139.58°-70099.742338109329840.6743787672
12-72.34°-165313.666629735033693.9894517456
13-161.50°1174.8380510598-154146.6649012470
1437.30°60175.773067955442213.0719235437

F#

letdeltaBearing(b1:double)(b2:double)=letr=(b2-b1)%360.0;ifr>180.0thenr-360.0elifr<-180.0thenr+360.0elser[<EntryPoint>]letmain_=printfn"%A"(deltaBearing20.045.0)printfn"%A"(deltaBearing-45.045.0)printfn"%A"(deltaBearing-85.090.0)printfn"%A"(deltaBearing-95.090.0)printfn"%A"(deltaBearing-45.0125.0)printfn"%A"(deltaBearing-45.0145.0)printfn"%A"(deltaBearing29.4803-88.6381)printfn"%A"(deltaBearing-78.3251-159.036)printfn"%A"(deltaBearing-70099.7423381093829840.67437876723)printfn"%A"(deltaBearing-165313.666629735733693.9894517456)printfn"%A"(deltaBearing1174.8380510598456-154146.66490124757)printfn"%A"(deltaBearing60175.7730679554642213.07192354373)0// return an integer exit code
Output:
25.090.0175.0-175.0170.0-170.0-118.1184-80.7109-139.5832831-72.34391852-161.502952337.29885559

Factor

Translation of:F#
Works with:Factor version 0.99 development release 2019-03-17
USING:combinatorsgeneralizationskernelmathprettyprint;IN:rosetta-code.bearings:delta-bearing(xy--z)swap-360mod{{[dup180>][360-]}{[dup-180<][360+]}[]}cond;:bearings-demo(--)20 45-45 45-85 90-95 90-45 125-45 14529.4803 -88.6381-78.3251 -159.036-70099.74233810938 29840.67437876723-165313.6666297357 33693.98945174561174.8380510598456 -154146.6649012475760175.77306795546 42213.07192354373[delta-bearing.]2 12mnapply;MAIN:bearings-demo
Output:
2590175-175170-170-118.1184-80.7109-139.5832831233856-72.34391851868713-161.502952307404537.29885558826936

Forth

Developed with Gforth 0.7.9_20211014 using floating point math.

:Angle-Difference-stack( b1 b2 - a +/-180)\ Algorithm  with stack manipulation without branches ( s. Frotran Groovy)fswapf-\ Delta angle360efswapfoverfmod\ mod 360fover1.5ef*f+\ +   540foverfmod\ mod 360fswapf2/f-\ -   180;:Angle-Difference-const( b1 b2 - a +/-180)\ Algorithm  without  Branches ( s. Fotran Groovy)fswapf-360efmod540ef+360efmod180ef-;\  Test Word  for  requested tests:test-ad( b1 b2 -- )foverfoverAngle-Difference-stackf.Angle-Difference-constf.;
Output:
20e                  45e                  test-ad 25. 25.  -45e                 45e                  test-ad 90. 90.  -85e                 90e                  test-ad 175. 175.  -95e                 90e                  test-ad -175. -175.  -45e                 125e                 test-ad 170. 170.  -45e                 145e                 test-ad -170. -170.  29.4803e             -88.6381e            test-ad -118.1184 -118.1184  -78.3251e            -159.036e            test-ad -80.7109 -80.7109  -70099.74233810938e  29840.67437876723e   test-ad -139.583283123386 -139.583283123386  -165313.6666297357e  33693.9894517456e    test-ad -72.3439185186871 -72.3439185186871  1174.8380510598456e  -154146.66490124757e test-ad -161.502952307404 -161.50295230740460175.77306795546e   42213.07192354373e   test-ad 37.2988555882694 37.2988555882694

Fortran

Rather than calculate angle differences and mess about with folding the results into ±180 and getting the sign right, why not use some mathematics? These days, trigonometrical functions are calculated swiftly by specialised hardware (well, microcode), and with the availability of functions working in degrees, matters are eased further nor is precision lost in converting from degrees to radians. So, the first step is to convert a bearing into an (x,y) unit vector via function CIS(t) = cos(t) + i.sin(t), which will handle all the annoyance of bearings specified in values above 360. Then, using the dot product of the two vectors allows the cosine of the angle to be known, and the cross product determines the sign.

However, this relies on the unit vectors being accurately so, and their subsequent dot product not exceeding one in size: given the rounding of results with the limited precision actual floating-point arithmetic, there may be problems. Proving that a calculation will not suffer these on a specific computer is difficult, especially as the desire for such a result may mean that any apparent pretext leading to that belief will be seized upon. Because calculations on the IBM pc and similar computers are conducted with 80-bit floating-point arithmetic, rounding errors for 64-bit results are likely to be small, but past experience leads to a "fog of fear" about the precise behaviour of floating-point arithmetic.

As it happens, the test data did not provoke any objections from the ACOSD function, but even so, a conversion to usingarctan instead ofarccos to recover angles would be safer. By using the four-quadrantarctan(x,y) function, the sign of the angle difference is also delivered and although that result could be in 0°-360° it turns out to be in ±180° as desired. On the other hand, the library of available functions did not include an arctan for complex parameters, so the complex number Z had to be split into its real and imaginary parts, thus requiring two appearances and to avoid repeated calculation, a temporary variable Z is needed. Otherwise, the statement could have been justT = ATAN2D(Z1*CONJG(Z2)) and the whole calculation could be effected in one statement,T = ATAN2D(CIS(90 - B1)*CONJG(CIS(90 - B2))) And, sincecis(t) = exp(i.t),T = ATAN2D(EXP(CMPLX(0,90 - B1))*CONJG(EXP(CMPLX(0,90 - B2)))) - although using the arithmetic statement function does seem less intimidating.

The source style is F77 (even using the old-style arithmetic statement function) except for the convenience of generic functions taking the type of their parameters to save on the bother of DCMPLX instead of just CMPLX, etc. Floating-point constants in the test data are specified with ~D0, the exponential form that signifies double precision otherwise they would be taken as single precision values. Some compilers offer an option stating that all floating-point constants are to be taken as double precision. REAL*8 precision amounts to about sixteen decimal digits, so some of the supplied values will not be accurately represented, unless something beyond REAL*8 is available.

SUBROUTINEBDIFF(B1,B2)!Difference B2 - B1, as bearings. All in degrees, not radians.REAL*8B1,B2!Maximum precision, for large-angle folding.COMPLEX*16CIS,Z1,Z2,Z!Scratchpads.CIS(T)=CMPLX(COSD(T),SIND(T))!Convert an angle into a unit vector.Z1=CIS(90-B1)!Bearings run clockwise from north (y) around to east (x).Z2=CIS(90-B2)!Mathematics runs counterclockwise from x (east).Z=Z1*CONJG(Z2)!(Z1x,Z1y)(Z2x,-Z2y) = (Z1x.Z2x + Z1y.Z2y, Z1y.Z2x - Z1x.Z2y)T=ATAN2D(AIMAG(Z),REAL(Z))!Madly, arctan(x,y) is ATAN(Y,X)!WRITE(6,10)B1,Z1,B2,Z2,T!Two sets of numbers, and a result.10FORMAT(2(F14.4,"(",F9.6,",",F9.6,")"),F9.3)!Two lots, and a tail.END SUBROUTINEBDIFF!Having functions in degrees saves some bother.PROGRAMORIENTEDREAL*8B(24)!Just prepare a wad of values.DATAB/20D0,45D0,-45D0,45D0,-85D0,90D0,-95D0,90D0,!As specified.1-45D0,125D0,-45D0,145D0,29.4803D0,-88.6381D0,2-78.3251D0,-159.036D0,3-70099.74233810938D0,29840.67437876723D0,4-165313.6666297357D0,33693.9894517456D0,51174.8380510598456D0,-154146.66490124757D0,660175.77306795546D0,42213.07192354373D0/WRITE(6,1)("B",I,"x","y",I=1,2)!Or, one could just list them twice.1FORMAT(28X,"Bearing calculations, in degrees"//*2(A13,I1,"(",A9,",",A9,")"),A9)!Compare format 10, above.DOI=1,23,2!Step through the pairs.CALLBDIFF(B(I),B(I+1))END DO      END

The output shows the stages:

                            Bearing calculations, in degrees            B1(        x,        y)            B2(        x,        y)       20.0000( 0.342020, 0.939693)       45.0000( 0.707107, 0.707107)   25.000      -45.0000(-0.707107, 0.707107)       45.0000( 0.707107, 0.707107)   90.000      -85.0000(-0.996195, 0.087156)       90.0000( 1.000000, 0.000000)  175.000      -95.0000(-0.996195,-0.087156)       90.0000( 1.000000, 0.000000) -175.000      -45.0000(-0.707107, 0.707107)      125.0000( 0.819152,-0.573576)  170.000      -45.0000(-0.707107, 0.707107)      145.0000( 0.573576,-0.819152) -170.000       29.4803( 0.492124, 0.870525)      -88.6381(-0.999718, 0.023767) -118.118      -78.3251(-0.979312, 0.202358)     -159.0360(-0.357781,-0.933805)  -80.711   -70099.7423( 0.984016,-0.178078)    29840.6744(-0.633734, 0.773551) -139.584  -165313.6666(-0.959667, 0.281138)    33693.9895(-0.559023,-0.829152)  -72.340     1174.8381( 0.996437,-0.084339)  -154146.6649(-0.918252, 0.395996) -161.510    60175.7731( 0.826820, 0.562467)    42213.0719( 0.998565,-0.053561)   37.297

FutureBasic

void local fn GetDifference(  b1 as float, b2 as float  )  float r = ( b2 - b1 ) mod 360.0  if r >= 180.0 then r = r - 360.0  printf @"%9.1f\u00B0 %10.1f\u00B0   = %7.1f\u00B0", b1, b2, rend fnprintf @"Input in -180 to +180 range:"printf @"-----------------------------------"printf @"%9s %12s %15s", "b1", "b2", "distance"printf @"-----------------------------------"fn GetDifference(  20.0,  45.0 )fn GetDifference( -45.0,  45.0 )fn GetDifference( -85.0,  90.0 )fn GetDifference( -95.0,  90.0 )fn GetDifference( -45.0, 125.0 )fn GetDifference( -45.0, 145.0 )fn GetDifference( -45.0, 125.0 )fn GetDifference( -45.0, 145.0 )fn GetDifference(  29.4803, -88.6381 )fn GetDifference( -78.3251, -159.036 )fn GetDifference( -70099.74233810938,   29840.67437876723 )fn GetDifference( -165313.6666297357,    33693.9894517456 )fn GetDifference( 1174.8380510598456, -154146.66490124757 )HandleEvents
Output:
-----------------------------------      b1          b2       distance-----------------------------------     20.0°       45.0°   =    25.0°    -45.0°       45.0°   =    90.0°    -85.0°       90.0°   =   175.0°    -95.0°       90.0°   =  -175.0°    -45.0°      125.0°   =   170.0°    -45.0°      145.0°   =  -170.0°    -45.0°      125.0°   =   170.0°    -45.0°      145.0°   =  -170.0°     29.5°      -88.6°   =  -118.1°    -78.3°     -159.0°   =   -80.7° -70099.7°    29840.7°   =  -139.6°-165313.7°    33694.0°   =   -72.3°   1174.8°  -154146.7°   =  -161.5°

Go

Basic task solution:

One feature of this solution is that if you can rely on the input bearings being in the range -180 to 180, you don't have to use math.Mod. Another feature is the bearing type and method syntax.

packagemainimport"fmt"typebearingfloat64vartestCases=[]struct{b1,b2bearing}{{20,45},{-45,45},{-85,90},{-95,90},{-45,125},{-45,145},{29.4803,-88.6381},{-78.3251,-159.036},}funcmain(){for_,tc:=rangetestCases{fmt.Println(tc.b2.Sub(tc.b1))}}func(b2bearing)Sub(b1bearing)bearing{switchd:=b2-b1;{cased<-180:returnd+360cased>180:returnd-360default:returnd}}
Output:
2590175-175170-170-118.1184-80.7109

Optional extra solution:

A feature here is that the function body is a one-liner sufficient for the task test cases.

packagemainimport("fmt""math")vartestCases=[]struct{b1,b2float64}{{20,45},{-45,45},{-85,90},{-95,90},{-45,125},{-45,145},{29.4803,-88.6381},{-78.3251,-159.036},{-70099.74233810938,29840.67437876723},{-165313.6666297357,33693.9894517456},{1174.8380510598456,-154146.66490124757},{60175.77306795546,42213.07192354373},}funcmain(){for_,tc:=rangetestCases{fmt.Println(angleDifference(tc.b2,tc.b1))}}funcangleDifference(b2,b1float64)float64{returnmath.Mod(math.Mod(b2-b1,360)+360+180,360)-180}
Output:
2590175-175170-170-118.11840000000001-80.71089999999998-139.58328312338563-72.34391851868713-161.5029523074044837.29885558826936

Groovy

Solution A:

Translation of:C++
defangleDifferenceA(doubleb1,doubleb2){r=(b2-b1)%360.0(r>180.0?r-360.0:r<=-180.0?r+360.0:r)}

Solution B:
In the spirit of theFortran "Why branch when you can math?" solution, but without all the messy trigonometry.

defangleDifferenceB(doubleb1,doubleb2){((b2-b1)%360.0-540.0)%360.0+180.0}

NOTE: We could ADD 540 and SUBTRACT 180 instead (as did many others, notably360_Assembly,NewLISP,Racket, andREXX). The difference is that my choice normalizes "about face" to +180° while the other (At least inGroovy and otherC-derived languages) normalizes "about face" to -180°.

Test:

println"         b1                      b2                      diff A                  diff B"[[b1:20,b2:45],[b1:-45,b2:45],[b1:-85,b2:90],[b1:-95,b2:90],[b1:-45,b2:125],[b1:-45,b2:145],[b1:29.4803,b2:-88.6381],[b1:-78.3251,b2:-159.036],[b1:-70099.74233810938,b2:29840.67437876723],[b1:-165313.6666297357,b2:33693.9894517456],[b1:1174.8380510598456,b2:-154146.66490124757],[b1:60175.77306795546,b2:42213.07192354373]].each{bearings->def(b1,b2)=bearings.values().collect{itasdouble}printf("%22.13f  %22.13f  %22.13f  %22.13f\n",b1,b2,angleDifferenceA(b1,b2),angleDifferenceB(b1,b2))}

Output:

         b1                      b2                      diff A                  diff B      20.0000000000000        45.0000000000000        25.0000000000000        25.0000000000000     -45.0000000000000        45.0000000000000        90.0000000000000        90.0000000000000     -85.0000000000000        90.0000000000000       175.0000000000000       175.0000000000000     -95.0000000000000        90.0000000000000      -175.0000000000000      -175.0000000000000     -45.0000000000000       125.0000000000000       170.0000000000000       170.0000000000000     -45.0000000000000       145.0000000000000      -170.0000000000000      -170.0000000000000      29.4803000000000       -88.6381000000000      -118.1184000000000      -118.1184000000000     -78.3251000000000      -159.0360000000000       -80.7109000000000       -80.7109000000000  -70099.7423381093800     29840.6743787672300      -139.5832831233856      -139.5832831233856 -165313.6666297357000     33693.9894517456000       -72.3439185186871       -72.3439185186871    1174.8380510598456   -154146.6649012475700      -161.5029523074045      -161.5029523074045   60175.7730679554600     42213.0719235437300        37.2988555882694        37.2988555882694

Haskell

importControl.Monad(join)importData.Bifunctor(bimap)importText.Printf(printf)typeRadians=FloattypeDegrees=Float---------- ANGLE DIFFERENCE BETWEEN TWO BEARINGS ---------bearingDelta::(Radians,Radians)->RadiansbearingDelta(a,b)-- sign * dot-product=sign*acos((ax*bx)+(ay*by))where(ax,ay)=(sina,cosa)(bx,by)=(sinb,cosb)sign|((ay*bx)-(by*ax))>0=1|otherwise=-1angleBetweenDegrees::(Degrees,Degrees)->DegreesangleBetweenDegrees=degrees.bearingDelta.joinbimapradians--------------------------- TEST -------------------------main::IO()main=putStrLn.unlines$fmap(uncurry(printf"%6.2f° - %6.2f°  ->  %7.2f°")<*>angleBetweenDegrees)[(20.0,45.0),(-45.0,45.0),(-85.0,90.0),(-95.0,90.0),(-45.0,125.0),(-45.0,145.0)]------------------------- GENERIC ------------------------degrees::Radians->Degreesdegrees=(/pi).(180*)radians::Degrees->Radiansradians=(/180).(pi*)
Output:
 20.00° -  45.00°  ->    25.00°-45.00° -  45.00°  ->    90.00°-85.00° -  90.00°  ->   175.00°-95.00° -  90.00°  ->  -175.00°-45.00° - 125.00°  ->   170.00°-45.00° - 145.00°  ->  -170.00°

J

relativeBearing=:180-360|180+-tests=:_99&".;._2noundefine20 45-45 45-85 90-95 90-45 125-45 14529.4803  -88.6381-78.3251  -159.036-70099.74233810938  29840.67437876723-165313.6666297357  33693.98945174561174.8380510598456  -154146.6649012475760175.77306795546  42213.07192354373)
   tests ,. relativeBearing/"1 tests      20       45       25     _45       45       90     _85       90      175     _95       90     _175     _45      125      170     _45      145     _170 29.4803 _88.6381 _118.118_78.3251 _159.036 _80.7109_70099.7  29840.7 _139.583 _165314    33694 _72.3439 1174.84  _154147 _161.503 60175.8  42213.1  37.2989

Java

Translation of:C++
publicclassAngleDifference{publicstaticdoublegetDifference(doubleb1,doubleb2){doubler=(b2-b1)%360.0;if(r<-180.0)r+=360.0;if(r>=180.0)r-=360.0;returnr;}publicstaticvoidmain(String[]args){System.out.println("Input in -180 to +180 range");System.out.println(getDifference(20.0,45.0));System.out.println(getDifference(-45.0,45.0));System.out.println(getDifference(-85.0,90.0));System.out.println(getDifference(-95.0,90.0));System.out.println(getDifference(-45.0,125.0));System.out.println(getDifference(-45.0,145.0));System.out.println(getDifference(-45.0,125.0));System.out.println(getDifference(-45.0,145.0));System.out.println(getDifference(29.4803,-88.6381));System.out.println(getDifference(-78.3251,-159.036));System.out.println("Input in wider range");System.out.println(getDifference(-70099.74233810938,29840.67437876723));System.out.println(getDifference(-165313.6666297357,33693.9894517456));System.out.println(getDifference(1174.8380510598456,-154146.66490124757));System.out.println(getDifference(60175.77306795546,42213.07192354373));}}
Output:
Input in -180 to +180 range25.090.0175.0-175.0170.0-170.0170.0-170.0-118.1184-80.7109Input in wider range-139.58328312338563-72.34391851868713-161.5029523074044837.29885558826936

JavaScript

ES5

This approach should be reliable but it is also very inefficient.

functionrelativeBearing(b1Rad,b2Rad){b1y=Math.cos(b1Rad);b1x=Math.sin(b1Rad);b2y=Math.cos(b2Rad);b2x=Math.sin(b2Rad);crossp=b1y*b2x-b2y*b1x;dotp=b1x*b2x+b1y*b2y;if(crossp>0.)returnMath.acos(dotp);return-Math.acos(dotp);}functiontest(){vardeg2rad=3.14159265/180.0;varrad2deg=180.0/3.14159265;return"Input in -180 to +180 range\n"+relativeBearing(20.0*deg2rad,45.0*deg2rad)*rad2deg+"\n"+relativeBearing(-45.0*deg2rad,45.0*deg2rad)*rad2deg+"\n"+relativeBearing(-85.0*deg2rad,90.0*deg2rad)*rad2deg+"\n"+relativeBearing(-95.0*deg2rad,90.0*deg2rad)*rad2deg+"\n"+relativeBearing(-45.0*deg2rad,125.0*deg2rad)*rad2deg+"\n"+relativeBearing(-45.0*deg2rad,145.0*deg2rad)*rad2deg+"\n"+relativeBearing(29.4803*deg2rad,-88.6381*deg2rad)*rad2deg+"\n"+relativeBearing(-78.3251*deg2rad,-159.036*deg2rad)*rad2deg+"\n"+"Input in wider range\n"+relativeBearing(-70099.74233810938*deg2rad,29840.67437876723*deg2rad)*rad2deg+"\n"+relativeBearing(-165313.6666297357*deg2rad,33693.9894517456*deg2rad)*rad2deg+"\n"+relativeBearing(1174.8380510598456*deg2rad,-154146.66490124757*deg2rad)*rad2deg+"\n"+relativeBearing(60175.77306795546*deg2rad,42213.07192354373*deg2rad)*rad2deg+"\n";}
Output:
Input in -180 to +180 range25.00000000000000490174.99999999999997-175.00000041135993170.00000000000003-170.00000041135996-118.1184-80.71089999999998Input in wider range-139.5833974814558-72.34414600076728-161.5027750112703337.2988761562732

ES6

(()=>{"use strict";// ------ ANGLE DIFFERENCE BETWEEN TWO BEARINGS ------// bearingDelta :: Radians -> Radians -> RadiansconstbearingDelta=a=>// The difference between two bearings: a and b.b=>{const[ax,ay]=[sin(a),cos(a)];const[bx,by]=[sin(b),cos(b)];// Cross-product above zero ?constsign=((ay*bx)-(by*ax))>0?(+1):-1;// Sign * dot-product.returnsign*acos((ax*bx)+(ay*by));};// ---------------------- TEST -----------------------// main :: IO ()constmain=()=>[[20,45],[-45,45],[-85,90],[-95,90],[-45,125],[-45,145]].map(xy=>showMap(...xy)).join("\n");// ------------------- FORMATTING --------------------// showMap :: Degrees -> Degrees -> StringconstshowMap=(da,db)=>{constdelta=degreesFromRadians(bearingDelta(radiansFromDegrees(da))(radiansFromDegrees(db))).toPrecision(4),theta=`${da}° +`.padStart(6," "),theta1=`${db}°  ->  `.padStart(11," "),diff=`${delta}°`.padStart(7," ");return`${theta}${theta1}${diff}`;};// --------------------- GENERIC ---------------------// radiansFromDegrees :: Float -> FloatconstradiansFromDegrees=n=>Pi*n/180.0;// degreesFromRadians :: Float -> FloatconstdegreesFromRadians=x=>180.0*x/Pi;// Abbreviations for trigonometric methods and// properties of the standard Math library.const[Pi,sin,cos,acos]=["PI","sin","cos","acos"].map(k=>Math[k]);// MAIN ---returnmain();})();
Output:
 20° +  45°  ->   25.00°-45° +  45°  ->   90.00°-85° +  90°  ->   175.0°-95° +  90°  ->  -175.0°-45° + 125°  ->   170.0°-45° + 145°  ->  -170.0°

Jsish

/* Angle difference between bearings, in Jsish */functionangleDifference(bearing1:number,bearing2:number):number{varangle=(bearing2-bearing1)%360;if(angle<-180)angle+=360;if(angle>=180)angle-=360;returnangle;}if(Interp.conf('unitTest')){vardataSet=[[20,45],[-45,45],[-85,90],[-95,90],[-45,125],[-45,145],[29.4803,-88.6381],[-78.3251,-159.036],[-70099.74233810938,29840.67437876723],[-165313.6666297357,33693.9894517456],[1174.8380510598456,-154146.66490124757],[60175.77306795546,42213.07192354373]];printf("         Bearing 1          Bearing 2         Difference\n");for(vari=0;i<dataSet.length;i++){printf("%17S° %17S° %17S°\n",dataSet[i][0],dataSet[i][1],angleDifference(dataSet[i][0],dataSet[i][1]));}}/*=!EXPECTSTART!=         Bearing 1          Bearing 2         Difference               20°                45°                25°              -45°                45°                90°              -85°                90°               175°              -95°                90°              -175°              -45°               125°               170°              -45°               145°              -170°          29.4803°          -88.6381°         -118.1184°         -78.3251°          -159.036°          -80.7109°-70099.7423381094°  29840.6743787672° -139.583283123386°-165313.666629736°  33693.9894517456° -72.3439185186871° 1174.83805105985° -154146.664901248° -161.502952307404° 60175.7730679555°  42213.0719235437°  37.2988555882694°=!EXPECTEND!=*/
Output:
prompt$ jsish -u angleDifference.jsi[PASS] angleDifference.jsi

jq

Works with:jq

Works with gojq, the Go implementation of jq

Note that the `%` operator in jq produces integral results.

# Angles are in degrees; the result is rounded to 4 decimal places:def subtract($b1; $b2):  10000 as $scale  | (($scale * ($b2 - $b1)) % (360 * $scale)) | round / $scale   | if   . < -180 then . + 360    elif . >= 180 then . - 360    else .    end; def pairs:     [ 20,  45],    [-45,  45],    [-85,  90],    [-95,  90],    [-45, 125],    [-45, 145],    [ 29.4803, -88.6381],    [-78.3251, -159.036],    [-70099.74233810938, 29840.67437876723],    [-165313.6666297357, 33693.9894517456],    [1174.8380510598456, -154146.66490124757],    [60175.77306795546, 42213.07192354373] ;"Differences (to 4dp) between these bearings:",( pairs as [$p0, $p1]  | subtract($p0; $p1) as $diff  | (if $p0 < 0 then " " else "  " end) as $offset  | "\($offset)\($p0) and \($p1) -> \($diff)" )
Output:
Differences (to 4dp) between these bearings:  20 and 45 -> 25 -45 and 45 -> 90 -85 and 90 -> 175 -95 and 90 -> -175 -45 and 125 -> 170 -45 and 145 -> -170  29.4803 and -88.6381 -> -118.1184 -78.3251 and -159.036 -> -80.7109 -70099.74233810938 and 29840.67437876723 -> -139.5833 -165313.6666297357 and 33693.9894517456 -> -72.344  1174.8380510598456 and -154146.66490124757 -> -161.5029  60175.77306795546 and 42213.07192354373 -> 37.2989


Differences (to 4dp) between these bearings:

 20 and 45 -> 25-45 and 45 -> 90-85 and 90 -> 175-95 and 90 -> -175-45 and 125 -> 170-45 and 145 -> -170 29.4803 and -88.6381 -> -118.1184-78.3251 and -159.036 -> -80.7109-70099.74233810938 and 29840.67437876723 -> -139.5833-165313.6666297357 and 33693.9894517456 -> -72.344 1174.8380510598456 and -154146.66490124757 -> -161.5029 60175.77306795546 and 42213.07192354373 -> 37.2989


Julia

Translation of:Python
usingPrintffunctionangdiff(a,b)r=(b-a)%360.0ifr180.0r-=360.0endreturnrendprintln("Input in -180 to +180 range:")for(a,b)in[(20.0,45.0),(-45.0,45.0),(-85.0,90.0),(-95.0,90.0),(-45.0,125.0),(-45.0,145.0),(-45.0,125.0),(-45.0,145.0),(29.4803,-88.6381),(-78.3251,-159.036)]@printf("% 6.1f -% 6.1f =% 6.1f\n",a,b,angdiff(a,b))endprintln("\nInput in wider range:")for(a,b)in[(-70099.74233810938,29840.67437876723),(-165313.6666297357,33693.9894517456),(1174.8380510598456,-154146.66490124757),(60175.77306795546,42213.07192354373)]@printf("% 9.1f -% 9.1f =% 6.1f\n",a,b,angdiff(a,b))end
Output:
Input in -180 to +180 range:  20.0 -   45.0 =   25.0 -45.0 -   45.0 =   90.0 -85.0 -   90.0 =  175.0 -95.0 -   90.0 = -175.0 -45.0 -  125.0 =  170.0 -45.0 -  145.0 = -170.0 -45.0 -  125.0 =  170.0 -45.0 -  145.0 = -170.0  29.5 -  -88.6 = -118.1 -78.3 - -159.0 =  -80.7Input in wider range: -70099.7 -   29840.7 = -139.6-165313.7 -   33694.0 =  -72.3   1174.8 - -154146.7 = -161.5  60175.8 -   42213.1 = -322.7

K

/ Angle difference between two angles/ angledif.kangdif:{[b1;b2];:[(r:(b2-b1)!360.0)<-180.0;r+:360.0;r>180.0;r-:360.0];:r}

The output of a session is given below:

Output:
K Console - Enter \ for help  \l angledif  angdif[20;45]25.0  angdif[-45;45]90.0  angdif[-85;90]175.0  angdif[-95;90]-175.0  angdif[-45;125]170.0  angdif[29.4803;-88.6381]-118.1184  angdif[-78.3251;-159.036]-80.7109  angdif[-70099.74233810938;29840.67437876723]-139.5833

Klingphix

Translation of:NewLISP
include ..\Utilitys.tlhy:bearing sub 360 mod 540 add 360 mod 180 sub ;20 45 bearing-45 45 bearing-85 90 bearing-95 90 bearing-45 125 bearing-45 145 bearing29.4803 -88.6381 bearing-78.3251 -159.036 bearing-70099.74233810938 29840.67437876723 bearing-165313.6666297357 33693.9894517456 bearing1174.8380510598456 -154146.66490124757 bearing60175.77306795546 42213.07192354373 bearingpstack" " input
Output:
(-25, -90, -175, 175, -170, 170, 118.118, 80.7109, 139.583, 72.3439, 161.503, -37.2989)

Kotlin

// version 1.1.2classAngle(d:Double){valvalue=when{din-180.0..180.0->dd>180.0->(d-180.0)%360.0-180.0else->(d+180.0)%360.0+180.0}operatorfunminus(other:Angle)=Angle(this.value-other.value)}funmain(args:Array<String>){valanglePairs=arrayOf(20.0to45.0,-45.0to45.0,-85.0to90.0,-95.0to90.0,-45.0to125.0,-45.0to145.0,29.4803to-88.6381,-78.3251to-159.036,-70099.74233810938to29840.67437876723,-165313.6666297357to33693.9894517456,1174.8380510598456to-154146.66490124757,60175.77306795546to42213.07192354373)println("       b1            b2           diff")valf="% 12.4f  % 12.4f  % 12.4f"for(apinanglePairs){valdiff=Angle(ap.second)-Angle(ap.first)println(f.format(ap.first,ap.second,diff.value))}}
Output:
       b1            b2           diff     20.0000       45.0000       25.0000    -45.0000       45.0000       90.0000    -85.0000       90.0000      175.0000    -95.0000       90.0000     -175.0000    -45.0000      125.0000      170.0000    -45.0000      145.0000     -170.0000     29.4803      -88.6381     -118.1184    -78.3251     -159.0360      -80.7109 -70099.7423    29840.6744     -139.5833-165313.6666    33693.9895      -72.3439   1174.8381  -154146.6649     -161.5030  60175.7731    42213.0719       37.2989

Lua

Each bearing will be stored in an object that inherits methods to accomplish all parts of the task: accept a new number of degrees, automatically adjusting to the range [-180, 180]; construct new bearing objects; subtract another bearing from itself and return the difference; construct a list of new bearing objects given a list of arbitrary degree sizes; and format the number of degrees into a modest human-readable format. Bearings will be zero-initialized by default if no degree size is provided.

bearing={degrees=0}-- prototype objectfunctionbearing:assign(angle)angle=tonumber(angle)or0whileangle>180doangle=angle-360endwhileangle<-180doangle=angle+360endself.degrees=angleendfunctionbearing:new(size)localchild_object={}setmetatable(child_object,{__index=self})child_object:assign(size)returnchild_objectendfunctionbearing:subtract(other)localdifference=self.degrees-other.degreesreturnself:new(difference)endfunctionbearing:list(sizes)localbearings={}forindex,sizeinipairs(sizes)dotable.insert(bearings,self:new(size))endreturnbearingsendfunctionbearing:text()returnstring.format("%.4f deg",self.degrees)endfunctionmain()localsubtrahends=bearing:list{20,-45,-85,-95,-45,-45,29.4803,-78.3251,-70099.74233810938,-165313.6666297357,1174.8380510598456,60175.77306795546}localminuends=bearing:list{45,45,90,90,125,145,-88.6381,-159.036,29840.67437876723,33693.9894517456,-154146.66490124757,42213.07192354373}forindex=1,#minuendsdolocalb2,b1=minuends[index],subtrahends[index]localb3=b2:subtract(b1)localstatement=string.format("%s - %s = %s\n",b2:text(),b1:text(),b3:text())io.write(statement)endendmain()
Output:
45.0000 deg - 20.0000 deg = 25.0000 deg45.0000 deg - -45.0000 deg = 90.0000 deg90.0000 deg - -85.0000 deg = 175.0000 deg90.0000 deg - -95.0000 deg = -175.0000 deg125.0000 deg - -45.0000 deg = 170.0000 deg145.0000 deg - -45.0000 deg = -170.0000 deg-88.6381 deg - 29.4803 deg = -118.1184 deg-159.0360 deg - -78.3251 deg = -80.7109 deg-39.3256 deg - 100.2577 deg = -139.5833 deg-146.0105 deg - -73.6666 deg = -72.3439 deg-66.6649 deg - 94.8381 deg = -161.5030 deg93.0719 deg - 55.7731 deg = 37.2989 deg

Maple

Translation of:C++
getDiff:=proc(b1,b2)localr:r:=frem(b2-b1,360):ifr>=180thenr:=r-360:fi:returnr:endproc:getDiff(20,45);getDiff(-45,45);getDiff(-85,90);getDiff(-95,90);getDiff(-45,125);getDiff(-45,145);getDiff(29.4803,-88.6381);getDiff(-78.3251,-159.036);getDiff(-70099.74233810938,29840.67437876723);getDiff(-165313.6666297357,33693.9894517456);getDiff(1174.8380510598456,-154146.66490124757);getDiff(60175.77306795546,42213.07192354373)
Output:
2590175-175170-170-118.1184-80.7109-139.58328-72.3340-161.503037.29885


Mathematica /Wolfram Language

ClearAll[AngleDifference]AngleDifference[b1_,b2_]:=Mod[b2-b1,360,-180]AngleDifference[20,45]AngleDifference[-45,45]AngleDifference[-85,90]AngleDifference[-95,90]AngleDifference[-45,125]AngleDifference[-45,145]AngleDifference[29.4803,-88.6381]AngleDifference[-78.3251,-159.036]AngleDifference[-70099.74233810938,29840.67437876723]AngleDifference[-165313.6666297357,33693.9894517456]AngleDifference[1174.8380510598456,-154146.66490124757]AngleDifference[60175.77306795546,42213.07192354373]
Output:
2590175-175170-170-118.118-80.7109-139.583-72.3439-161.50337.2989

Maxima

Translation of:R
diff_bearing(b1,b2):=block(r:mod(b2-b1,360),ifr>180thenr-360elser)$test_bearings:[[20,45],[-45,45],[-85,90],[-95,90],[-45,125],[-45,145],[29.4803,-88.6381],[-78.3251,-159.036]]$big_bearings:[[-70099.74233810938,29840.67437876723],[-165313.6666297357,33693.9894517456],[1174.8380510598456,-154146.66490124757],[60175.77306795546,42213.07192354373]]$db_unary(list):=map(lambda([l],apply(diff_bearing,l)),list)$db_unary(test_bearings);db_unary(big_bearings);
Output:
[25,90,175,-175,170,-170,-118.11840000000001,-80.71089999999998][-139.58328312338563,-72.34391851868713,-161.50295230740448,37.29885558826936]

Modula-2

Translation of:Java
FROMTerminalIMPORT*;PROCEDUREWriteRealLn(value:REAL);VARstr:ARRAY[0..16]OFCHAR;BEGINRealToStr(value,str);WriteString(str);WriteLn;ENDWriteRealLn;PROCEDUREAngleDifference(b1,b2:REAL):REAL;VARr:REAL;BEGINr:=(b2-b1);WHILEr<-180.0DOr:=r+360.0;END;WHILEr>=180.0DOr:=r-360.0;END;RETURNr;ENDAngleDifference;BEGINWriteString('Input in -180 to +180 range');WriteLn;WriteRealLn(AngleDifference(20.0,45.0));WriteRealLn(AngleDifference(-45.0,45.0));WriteRealLn(AngleDifference(-85.0,90.0));WriteRealLn(AngleDifference(-95.0,90.0));WriteRealLn(AngleDifference(-45.0,125.0));WriteRealLn(AngleDifference(-45.0,145.0));WriteRealLn(AngleDifference(29.4803,-88.6381));WriteRealLn(AngleDifference(-78.3251,-159.036));WriteString('Input in wider range');WriteLn;WriteRealLn(AngleDifference(-70099.74233810938,29840.67437876723));WriteRealLn(AngleDifference(-165313.6666297357,33693.9894517456));WriteRealLn(AngleDifference(1174.8380510598456,-154146.66490124757));WriteRealLn(AngleDifference(60175.77306795546,42213.07192354373));ReadChar;ENDBearings.

NewLISP

Taken from Racket solution

#!/usr/bin/envnewlisp(define(bearing-bearingheading)(sub(mod(add(mod(subbearingheading)360.0)540.0)360.0)180.0))(bearing-2045)(bearing--4545)(bearing--8590)(bearing--9590)(bearing--45125)(bearing--45145)(bearing-29.4803-88.6381)(bearing--78.3251-159.036)(bearing--70099.7423381093829840.67437876723)(bearing--165313.666629735733693.9894517456)(bearing-1174.8380510598456-154146.66490124757)(bearing-60175.7730679554642213.07192354373))
Output:
-25-90-175175-170170118.1183999999999580.71090000000004139.5832831233856372.34391851868713161.50295230740448-37.29885558826936

Nim

importmathimportstrutilsprocdelta(b1,b2:float):float=result=(b2-b1)mod360.0ifresult<-180.0:result+=360.0elifresult>=180.0:result-=360.0lettestVectors:seq[tuple[b1,b2:float]]=@[(20.00,45.00),(-45.00,45.00),(-85.00,90.00),(-95.00,90.00),(-45.00,125.00),(-45.00,145.00),(29.48,-88.64),(-78.33,-159.04),(-70099.74,29840.67),(-165313.67,33693.99),(1174.84,-154146.66),(60175.77,42213.07)]forvectorintestVectors:echovector.b1.formatFloat(ffDecimal,2).align(13)&vector.b2.formatFloat(ffDecimal,2).align(13)&delta(vector.b1,vector.b2).formatFloat(ffDecimal,2).align(13)
Output:
                20.00        45.00        25.00       -45.00        45.00        90.00       -85.00        90.00       175.00       -95.00        90.00      -175.00       -45.00       125.00       170.00       -45.00       145.00      -170.00        29.48       -88.64      -118.12       -78.33      -159.04       -80.71    -70099.74     29840.67      -139.59   -165313.67     33693.99       -72.34      1174.84   -154146.66      -161.50     60175.77     42213.07        37.30

Nutt

Translation of:Java
module mainimports native.io.output.sayfunct get_difference(b1:Float,b2:Float):Float=var r:Float=(b2-b1)%360.0doif r< -180.0 r=r+360.0doif r>=180.0 r=r-360.0yield rreturnsay("Input in -180 to +180 range")say(get_difference(20.0,45.0))say(get_difference(-45.0,45.0))say(get_difference(-85.0,90.0))say(get_difference(-95.0,90.0))say(get_difference(-45.0,125.0))say(get_difference(-45.0,145.0))say(get_difference(-45.0,125.0))say(get_difference(-45.0,145.0))say(get_difference(29.4803,-88.6381))say(get_difference(-78.3251,-159.036))say("Input in wider range")say(get_difference(-70099.74233810938,29840.67437876723))say(get_difference(-165313.6666297357,33693.9894517456))say(get_difference(1174.8380510598456,-154146.66490124757))say(get_difference(60175.77306795546,42213.07192354373))end
Output:
Input in -180 to +180 range25.090.0175.0-175.0170.0-170.0170.0-170.0-118.1184-80.7109Input in wider range-139.58328312339-72.3439185187-161.502952307415637.29885558827

Objeck

Translation of:Java
class AngleBearings {   function : Main(args : String[]) ~ Nil {      "Input in -180 to +180 range"->PrintLine();      GetDifference(20.0, 45.0)->PrintLine();      GetDifference(-45.0, 45.0)->PrintLine();      GetDifference(-85.0, 90.0)->PrintLine();      GetDifference(-95.0, 90.0)->PrintLine();      GetDifference(-45.0, 125.0)->PrintLine();      GetDifference(-45.0, 145.0)->PrintLine();      GetDifference(-45.0, 125.0)->PrintLine();      GetDifference(-45.0, 145.0)->PrintLine();      GetDifference(29.4803, -88.6381)->PrintLine();      GetDifference(-78.3251, -159.036)->PrintLine();      "Input in wider range"->PrintLine();      GetDifference(-70099.74233810938, 29840.67437876723)->PrintLine();      GetDifference(-165313.6666297357, 33693.9894517456)->PrintLine();      GetDifference(1174.8380510598456, -154146.66490124757)->PrintLine();      GetDifference(60175.77306795546, 42213.07192354373)->PrintLine();   }   function : native : GetDifference(b1 : Float, b2 : Float) ~ Float {      r := Float->Mod(b2 - b1, 360.0);      if (r < -180.0) {         r += 360.0;      };      if (r >= 180.0) {         r -= 360.0;      };      return r;   }}
Output:
Input in -180 to +180 range2590175-175170-170170-170-118.118-80.7109Input in wider range-139.583-72.3439-161.50337.2989

OCaml

Translation of:D
letget_diffb1b2=letr=mod_float(b2-.b1)360.0inifr<-180.0thenr+.360.0elseifr>=180.0thenr-.360.0elserlet()=print_endline"Input in -180 to +180 range";Printf.printf" %g\n"(get_diff20.045.0);Printf.printf" %g\n"(get_diff(-45.0)45.0);Printf.printf" %g\n"(get_diff(-85.0)90.0);Printf.printf" %g\n"(get_diff(-95.0)90.0);Printf.printf" %g\n"(get_diff(-45.0)125.0);Printf.printf" %g\n"(get_diff(-45.0)145.0);Printf.printf" %g\n"(get_diff(-45.0)125.0);Printf.printf" %g\n"(get_diff(-45.0)145.0);Printf.printf" %g\n"(get_diff29.4803(-88.6381));Printf.printf" %g\n"(get_diff(-78.3251)(-159.036));print_endline"Input in wider range";Printf.printf" %g\n"(get_diff(-70099.74233810938)29840.67437876723);Printf.printf" %g\n"(get_diff(-165313.6666297357)33693.9894517456);Printf.printf" %g\n"(get_diff1174.8380510598456(-154146.66490124757));Printf.printf" %g\n"(get_diff60175.7730679554642213.07192354373);;;
Output:
Input in -180 to +180 range 25 90 175 -175 170 -170 170 -170 -118.118 -80.7109Input in wider range -139.583 -72.3439 -161.503 37.2989

PARI/GP

centerliftmod1(x)=frac(x+1/2)-1/2;anglediff(x,y)=centerliftmod1((y-x)/360)*360;vecFunc(f)=v->call(f,v);apply(vecFunc(anglediff), [[20,45], [-45,45], [-85,90], [-95,90], [-45,125], [-45,145], [29.4803,-88.6381], [-78.3251,-159.036], [-70099.74233810938,29840.67437876723], [-165313.6666297357,33693.9894517456], [1174.8380510598456,-154146.66490124757], [60175.77306795546,42213.07192354373]])
Output:
%1 = [25, 90, 175, -175, 170, -170, -118.11840000000000000000000000000000000, -80.710900000000000000000000000000000000, -139.58328312339000000000000000000000023, -72.343918518700000000000000000000000733, -161.50295230741560000000000000000000000, 37.298855588269999999999999999999999909]

Pascal

This program is meant to be saved in the same folder as a fileangles.txt containing the input. Each pair of angles to subtract appears on its own line in the input file.

ProgramBearings;{ Reads pairs of angles from a file and subtracts them }ConstfileName='angles.txt';Typedegrees=real;Varsubtrahend,minuend:degrees;angleFile:text;functionSimplify(angle:degrees):degrees;{ Returns an number in the range [-180.0, 180.0] }beginwhileangle>180.0doangle:=angle-360.0;whileangle<-180.0doangle:=angle+360.0;Simplify:=angleend;functionDifference(b1,b2:degrees):degrees;{ Subtracts b1 from b2 and returns a simplified result }beginDifference:=Simplify(b2-b1)end;procedureSubtract(b1,b2:degrees);{ Subtracts b1 from b2 and shows the whole equation onscreen }varb3:degrees;beginb3:=Difference(b1,b2);writeln(b2:20:11,'   - ',b1:20:11,'   = ',b3:20:11)end;Beginassign(angleFile,fileName);reset(angleFile);whilenoteof(angleFile)dobeginreadln(angleFile,subtrahend,minuend);Subtract(subtrahend,minuend)end;close(angleFile)End.
Input:
                20                    45               -45                    45               -85                    90               -95                    90               -45                   125               -45                   145           29.4803              -88.6381          -78.3251              -159.036-70099.74233810938     29840.67437876723-165313.6666297357      33693.98945174561174.8380510598456   -154146.66490124757 60175.77306795546     42213.07192354373
Output:
     45.00000000000   -       20.00000000000   =       25.00000000000     45.00000000000   -      -45.00000000000   =       90.00000000000     90.00000000000   -      -85.00000000000   =      175.00000000000     90.00000000000   -      -95.00000000000   =     -175.00000000000    125.00000000000   -      -45.00000000000   =      170.00000000000    145.00000000000   -      -45.00000000000   =     -170.00000000000    -88.63810000000   -       29.48030000000   =     -118.11840000000   -159.03600000000   -      -78.32510000000   =      -80.71090000000  29840.67437876723   -   -70099.74233810938   =     -139.58328312339  33693.98945174560   -  -165313.66662973570   =      -72.34391851869-154146.66490124760   -     1174.83805105985   =     -161.50295230740  42213.07192354373   -    60175.77306795546   =       37.29885558827

Pascal-P

Translation of:C++
Works with:Pascal-P version P4
programanglebearings(output);(* Angle difference between two bearings *)functionrmod(x1,x2:real):real;beginrmod:=x1-trunc(x1/x2)*x2;end;functiongetdiff(b1,b2:real):real;varr:real;beginr:=rmod((b2-b1),360.0);ifr>=180.0thenr:=r-360.0;ifr<-180.0thenr:=r+360.0;getdiff:=r;end;procedurewriterow(b1,b2:real);beginwriteln(b1:14,'    ',b2:14,'    ',getdiff(b1,b2):14);end;beginwriteln('Input in -180 to +180 range');writeln('     Bearing 1         Bearing 2        Difference');writerow(20.0,45.0);writerow(-45.0,45.0);writerow(-85.0,90.0);writerow(-95.0,90.0);writerow(-45.0,125.0);writerow(-45.0,145.0);writerow(-45.0,125.0);writerow(-45.0,145.0);writerow(29.4803,-88.6381);writerow(-78.3251,-159.036);writeln;writeln('Input in wider range');writeln('     Bearing 1         Bearing 2        Difference');writerow(-70099.74233810938,29840.67437876723);writerow(-165313.6666297357,33693.9894517456);writerow(1174.8380510598456,-154146.66490124757);writerow(60175.77306795546,42213.07192354373)end.
Output:
Input in -180 to +180 range     Bearing 1         Bearing 2        Difference 2.0000000e+01     4.5000000e+01     2.5000000e+01-4.5000000e+01     4.5000000e+01     9.0000000e+01-8.5000000e+01     9.0000000e+01     1.7500000e+02-9.5000000e+01     9.0000000e+01    -1.7500000e+02-4.5000000e+01     1.2500000e+02     1.7000000e+02-4.5000000e+01     1.4500000e+02    -1.7000000e+02-4.5000000e+01     1.2500000e+02     1.7000000e+02-4.5000000e+01     1.4500000e+02    -1.7000000e+02 2.9480300e+01    -8.8638100e+01    -1.1811840e+02-7.8325100e+01    -1.5903600e+02    -8.0710900e+01Input in wider range     Bearing 1         Bearing 2        Difference-7.0099742e+04     2.9840674e+04    -1.3958328e+02-1.6531367e+05     3.3693989e+04    -7.2343919e+01 1.1748381e+03    -1.5414666e+05    -1.6150295e+02 6.0175773e+04     4.2213072e+04     3.7298856e+01

PascalABC.NET

functiondelta(b1,b2:real):real;beginresult:=(b2-b1)-Trunc((b2-b1)/360.0)*360.0;ifresult<-180.0thenresult+=360.0elseifresult>=180.0thenresult-=360.0end;beginvartestVectors:=|(20.00,45.00),(-45.00,45.00),(-85.00,90.00),(-95.00,90.00),(-45.00,125.00),(-45.00,145.00),(29.48,-88.64),(-78.33,-159.04),(-70099.74,29840.67),(-165313.67,33693.99),(1174.84,-154146.66),(60175.77,42213.07)|;foreachvarvectorintestVectorsdowriteln(vector[0]:10:2,vector[1]:12:2,delta(vector[0],vector[1]):10:2);end.

Perl

Perl's built-in modulo is integer-only, so import a suitable one from thePOSIX core module

usePOSIX'fmod';subangle{my($b1,$b2)=@_;my$b=fmod(($b2-$b1+720),360);$b-=360if$b>180;$b+=360if$b<-180;return$b;}@bearings=(20,45,-45,45,-85,90,-95,90,-45,125,-45,145,29.4803,-88.6381,-78.3251,-159.036,-70099.74233810938,29840.67437876723,-165313.6666297357,33693.9894517456,1174.8380510598456,-154146.66490124757,60175.77306795546,42213.07192354373);while(my($b1,$b2)=splice(@bearings,0,2)){printf"%10.2f %10.2f = %8.2f\n",$b1,$b2,angle($b1,$b2);}
Output:
     20.00      45.00 =    25.00    -45.00      45.00 =    90.00    -85.00      90.00 =   175.00    -95.00      90.00 =  -175.00    -45.00     125.00 =   170.00    -45.00     145.00 =  -170.00     29.48     -88.64 =  -118.12    -78.33    -159.04 =   -80.71 -70099.74   29840.67 =  -139.58-165313.67   33693.99 =   -72.34   1174.84 -154146.66 =  -161.50  60175.77   42213.07 =    37.30

Phix

functiontz(atoma)-- trim trailing zeroes and decimal pointstringres=sprintf("%16f",a)fori=length(res)to1by-1dointegerch=res[i]ifch='0'orch='.'thenres[i]=' 'endififch!='0'thenexitendifendforreturnresendfunctionproceduretest(atomb1,b2)atomdiff=mod(b2-b1,360)diff-=iff(diff>180?360:0)printf(1,"%s %s %s\n",{tz(b1),tz(b2),tz(diff)})endprocedureputs(1,"       b1               b2             diff\n")puts(1,"---------------- ---------------- ----------------\n")test(20,45)test(-45,45)test(-85,90)test(-95,90)test(-45,125)test(-45,145)test(29.4803,-88.6381)test(-78.3251,-159.036)test(-70099.74233810938,29840.67437876723)test(-165313.6666297357,33693.9894517456)test(1174.8380510598456,-154146.66490124757)test(60175.77306795546,42213.07192354373)
Output:
       b1               b2             diff---------------- ---------------- ----------------       20               45               25      -45               45               90      -85               90              175      -95               90             -175      -45              125              170      -45              145             -170       29.4803         -88.6381        -118.1184      -78.3251        -159.036          -80.7109   -70099.742338     29840.674379      -139.583283  -165313.66663      33693.989452       -72.343919     1174.838051   -154146.664901      -161.502952    60175.773068     42213.071924        37.298856

Phixmonti

include ..\Utilitys.pmt( "16" 1 "16" 1 "16" ) var aldef difAngle    /# b1 b2 -- diff #/    swap - 360 mod    dup 180 > if 360 - endifenddefdef test    /# b1 b2 -- #/    over over difAngle >ps swap " " rot " " ps> 5 tolist    al lalign ?enddef( "b1" " " "b2" " " "diff" ) al lalign ?"---------------- ---------------- ----------------" ?20 45 test-45 45 test-85 90 test-95 90 test-45 125 test-45 145 test29.4803 -88.6381 test-78.3251 -159.036 test-70099.74233810938 29840.67437876723 test-165313.6666297357 33693.9894517456 test1174.8380510598456 -154146.66490124757 test60175.77306795546 42213.07192354373 test
Output:
       b1               b2              diff---------------- ---------------- ----------------       20               45               25       -45              45               90       -85              90               175       -95              90              -175       -45              125              170       -45              145             -170     29.4803     -88.638099999999 -118.11840000000-78.325100000000 -159.03600000000 -80.710899999999-70099.742338109 29840.6743787672 -139.58328312338-165313.66662973 33693.9894517455 -72.3439185186871174.83805105984 -154146.66490124 -161.5029523074060175.7730679554 42213.0719235437 37.2988555882693=== Press any key to exit ===

PHP

Translation of:ANSI BASIC
<?php// Angle difference between two bearingsfunctionget_diff($b1,$b2){$r=($b2-$b1)-intdiv($b2-$b1,360)*360;if($r>180.0)$r-=360.0;if($r<-180.0)$r+=360.0;return$r;}functionecho_row($b1,$b2){echostr_pad(number_format($b1,6,".",""),14," ",STR_PAD_LEFT).'    ';echostr_pad(number_format($b2,6,".",""),14," ",STR_PAD_LEFT).'    ';echostr_pad(number_format(get_diff($b1,$b2),6),14," ",STR_PAD_LEFT);echo"\n";}echo"Input in -180 to +180 range\n";echo"     Bearing 1         Bearing 2        Difference\n";echo_row(20.0,45.0);echo_row(-45.0,45.0);echo_row(-85.0,90.0);echo_row(-95.0,90.0);echo_row(-45.0,125.0);echo_row(-45.0,145.0);echo_row(-45.0,125.0);echo_row(-45.0,145.0);echo_row(29.4803,-88.6381);echo_row(-78.3251,-159.036);echo"\nInput in wider range\n";echo"     Bearing 1         Bearing 2        Difference\n";echo_row(-70099.74233810938,29840.67437876723);echo_row(-165313.6666297357,33693.9894517456);echo_row(1174.8380510598456,-154146.66490124757);echo_row(60175.77306795546,42213.07192354373);?>
Output:
Input in -180 to +180 range     Bearing 1         Bearing 2        Difference     20.000000         45.000000         25.000000    -45.000000         45.000000         90.000000    -85.000000         90.000000        175.000000    -95.000000         90.000000       -175.000000    -45.000000        125.000000        170.000000    -45.000000        145.000000       -170.000000    -45.000000        125.000000        170.000000    -45.000000        145.000000       -170.000000     29.480300        -88.638100       -118.118400    -78.325100       -159.036000        -80.710900Input in wider range     Bearing 1         Bearing 2        Difference -70099.742338      29840.674379       -139.583283-165313.666630      33693.989452        -72.343919   1174.838051    -154146.664901       -161.502952  60175.773068      42213.071924         37.298856

Pluto

Translation of:Wren
Library:Pluto-math2
require"math2"localfunctionsubtract(b1,b2)locald=(b2-b1)%360ifd<-180thend+=360endifd>=180thend-=360endreturnmath.toplaces(d,4)endlocalpairs={{20,45},{-45,45},{-85,90},{-95,90},{-45,125},{-45,145},{29.4803,-88.6381},{-78.3251,-159.036},{-70099.74233810938,29840.67437876723},{-165313.6666297357,33693.9894517456},{1174.8380510598456,-154146.66490124757},{60175.77306795546,42213.07192354373}}print("Differences (to 4dp) between these bearings:")forpairsaspairdolocal[p1,p2]=pairlocaldiff=subtract(p1,p2)localoffset=p1<0?" ":"  "print($"{offset}{p1} and {p2} -> {diff}")end
Output:
Differences (to 4dp) between these bearings:  20 and 45 -> 25.0 -45 and 45 -> 90.0 -85 and 90 -> 175.0 -95 and 90 -> -175.0 -45 and 125 -> 170.0 -45 and 145 -> -170.0  29.4803 and -88.6381 -> -118.1184 -78.3251 and -159.036 -> -80.7109 -70099.742338109 and 29840.674378767 -> -139.5833 -165313.66662974 and 33693.989451746 -> -72.3439  1174.8380510598 and -154146.66490125 -> -161.503  60175.773067955 and 42213.071923544 -> 37.2989

PowerShell

This implementation takes two user inputs withGet-AngleDiff or prints the examples withGet-Examples. There is also a full help file accessed by typingGet-Help Get-AngleDiff -full

<#.Synopsis   Gets the difference between two angles between the values of -180 and 180.   To see examples use "Get-Examples".DESCRIPTION   This code uses the modulo operator, this is represented with the "%".   The  modulo operator returns the remainder after division, as displayed below   3 % 2 = 1   20 % 15 = 5   200 % 146 = 54.EXAMPLE    PS C:\WINDOWS\system32> Get-AngleDiff    cmdlet Get-AngleDiff at command pipeline position 1    Supply values for the following parameters:    angle1: 45    angle2: -85    The difference between 45 and -85 is -130    PS C:\WINDOWS\system32>.EXAMPLE    PS C:\WINDOWS\system32> Get-AngleDiff -angle1 50 -angle2 -65    The difference between 50 and -65 is -115    PS C:\WINDOWS\system32>.EXAMPLE    PS C:\WINDOWS\system32> Get-AngleDiff -89 50    The difference between -89 and 50 is 139    PS C:\WINDOWS\system32>#>functionGet-AngleDiff{[CmdletBinding()]Param(# Angle one input, must be a number[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][double]$angle1,# Angle two input, must be a number[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][double]$angle2)Begin{#This is the equation to calculate the difference[double]$Difference=($angle2-$angle1)%360.0}Process{#If/IfElse/Else block to return results within the requested rangeif($Difference-lt-180.0){$Difference+=360.0}elseif($Difference-gt360.0){$Difference-=360.0}#Writes the values given by the user and the resultWrite-Host"The difference between $angle1 and $angle2 is $Difference"}End{}}<#.Synopsis   This is simply the outputs of the Get-AngleDiff Function in a function.EXAMPLEPS C:\WINDOWS\system32> Get-ExamplesInputs from the -180 to 180 rangeThe difference between 20 and 45 is 25The difference between -45 and 45 is 90The difference between -85 and 90 is 175The difference between -95 and 90 is 185The difference between -45 and 125 is 170The difference between -45 and 145 is 190The difference between -45 and 125 is 170The difference between -45 and 145 is 190The difference between 29.4803 and -88.6381 is -118.1184The difference between -78.3251 and -159.036 is -80.7109Inputs from a wider rangeThe difference between -70099.7423381094 and 29840.6743787672 is 220.416716876614The difference between -165313.666629736 and 33693.9894517456 is 287.656081481313The difference between 1174.83805105985 and -154146.664901248 is -161.502952307404The difference between 60175.7730679555 and 42213.0719235437 is 37.2988555882694PS C:\WINDOWS\system32>#>functionGet-Examples{#blank write-host is used for a blank line to make the output look a lil cleanerWrite-HostWrite-Host"Inputs from the -180 to 180 range"Get-AngleDiff20.045.0Get-AngleDiff-45.045.0Get-AngleDiff-85.090.0Get-AngleDiff-95.090.0Get-AngleDiff-45.0125.0Get-AngleDiff-45.0145.0Get-AngleDiff-45.0125.0Get-AngleDiff-45.0145.0Get-AngleDiff29.4803-88.6381Get-AngleDiff-78.3251-159.036Write-HostWrite-Host"Inputs from a wider range"Get-AngleDiff-70099.7423381093829840.67437876723Get-AngleDiff-165313.666629735733693.9894517456Get-AngleDiff1174.8380510598456-154146.66490124757Get-AngleDiff60175.7730679554642213.07192354373}

Results of user inputs
using -45 and 98 withGet-AngleDiff:

PSC:\WINDOWS\system32>Get-AngleDiff-4598Thedifferencebetween-45and98is143

Results ofGet-Examples

PS C:\WINDOWS\system32> Get-ExamplesInputs from the -180 to 180 rangeThe difference between 20 and 45 is 25The difference between -45 and 45 is 90The difference between -85 and 90 is 175The difference between -95 and 90 is 185The difference between -45 and 125 is 170The difference between -45 and 145 is 190The difference between -45 and 125 is 170The difference between -45 and 145 is 190The difference between 29.4803 and -88.6381 is -118.1184The difference between -78.3251 and -159.036 is -80.7109Inputs from a wider rangeThe difference between -70099.7423381094 and 29840.6743787672 is 220.416716876614The difference between -165313.666629736 and 33693.9894517456 is 287.656081481313The difference between 1174.83805105985 and -154146.664901248 is -161.502952307404The difference between 60175.7730679555 and 42213.0719235437 is 37.2988555882694

Another solution

In "traditional" algorithmic style.

Translation of:ANSI BASIC
# Angle difference between two bearingsfunctionGet-Diff([double]$B1,[double]$B2){$r=($B2-$B1)%360.0if($r-lt-180.0){$r+=360.0}if($r-ge180.0){$r-=360.0}return[double]$r}functionWrite-Row([double]$B1,[double]$B2){[string]$out="$($B1.ToString('#######.000000').PadLeft(14,' '))"$out+="$($B2.ToString('#######.000000').PadLeft(14,' '))"$out+="$((Get-Diff$B1$B2).ToString('#######.000000').PadLeft(14,' '))"Write-Output$out}Write-Output"Input in -180 to +180 range"Write-Output"     Bearing 1         Bearing 2        Difference"Write-Row20.045.0Write-Row-45.045.0Write-Row-85.090.0Write-Row-95.090.0Write-Row-45.0125.0Write-Row-45.0145.0Write-Row-45.0125.0Write-Row-45.0145.0Write-Row29.4803-88.6381Write-Row-78.3251-159.036Write-Output""Write-Output"Input in wider range"Write-Output"     Bearing 1         Bearing 2        Difference"Write-Row-70099.7423381093829840.67437876723Write-Row-165313.666629735733693.9894517456Write-Row1174.8380510598456-154146.66490124757Write-Row60175.7730679554642213.07192354373
Output:

Format of numbers (decimal comma or dot) depends on a culture settings.

Input in -180 to +180 range     Bearing 1         Bearing 2        Difference     20,000000         45,000000         25,000000    -45,000000         45,000000         90,000000    -85,000000         90,000000        175,000000    -95,000000         90,000000       -175,000000    -45,000000        125,000000        170,000000    -45,000000        145,000000       -170,000000    -45,000000        125,000000        170,000000    -45,000000        145,000000       -170,000000     29,480300        -88,638100       -118,118400    -78,325100       -159,036000        -80,710900Input in wider range     Bearing 1         Bearing 2        Difference -70099,742338      29840,674379       -139,583283-165313,666630      33693,989452        -72,343919   1174,838051    -154146,664901       -161,502952  60175,773068      42213,071924         37,298856

Python

Translation of:C++
from__future__importprint_functiondefgetDifference(b1,b2):r=(b2-b1)%360.0# Python modulus has same sign as divisor, which is positive here,# so no need to consider negative caseifr>=180.0:r-=360.0returnrif__name__=="__main__":print("Input in -180 to +180 range")print(getDifference(20.0,45.0))print(getDifference(-45.0,45.0))print(getDifference(-85.0,90.0))print(getDifference(-95.0,90.0))print(getDifference(-45.0,125.0))print(getDifference(-45.0,145.0))print(getDifference(-45.0,125.0))print(getDifference(-45.0,145.0))print(getDifference(29.4803,-88.6381))print(getDifference(-78.3251,-159.036))print("Input in wider range")print(getDifference(-70099.74233810938,29840.67437876723))print(getDifference(-165313.6666297357,33693.9894517456))print(getDifference(1174.8380510598456,-154146.66490124757))print(getDifference(60175.77306795546,42213.07192354373))
Output:
Input in -180 to +180 range25.090.0175.0-175.0170.0-170.0170.0-170.0-118.11840000000001-80.71089999999998Input in wider range-139.58328312338563-72.34391851868713-161.5029523074044837.29885558826936


Or, generalising a little by deriving the degrees from a (Radians -> Radians) function, and formatting the output in columns:

Works with:Python version 3.7
'''Difference between two bearings'''frommathimport(acos,cos,pi,sin)# bearingDelta :: Radians -> Radians -> RadiansdefbearingDelta(ar):'''Difference between two bearings,       expressed in radians.'''defgo(br):[(ax,ay),(bx,by)]=[(sin(x),cos(x))forxin[ar,br]]# cross-product > 0 ?sign=+1if0<((ay*bx)-(by*ax))else-1# sign * dot-productreturnsign*acos((ax*bx)+(ay*by))returnlambdabr:go(br)# TEST ----------------------------------------------------# main :: IO ()defmain():'''Test and display'''# showMap :: Degrees -> Degrees -> StringdefshowMap(da,db):returnunwords(str(x).rjust(n)forn,xin[(22,str(da)+' +'),(24,str(db)+'  -> '),(7,round(degrees(bearingDelta(radians(da))(radians(db))),2))])print(__doc__+':')print(unlines(showMap(a,b)fora,bin[(20,45),(-45,45),(-85,90),(-95,90),(-45,125),(-45,145),(-70099.74233810938,29840.67437876723),(-165313.6666297357,33693.9894517456),(1174.8380510598456,-154146.66490124757),(60175.77306795546,42213.07192354373)]))# GENERIC ----------------------------------------------# radians :: Float x => Degrees x -> Radians xdefradians(x):'''Radians derived from degrees.'''returnpi*x/180# degrees :: Float x => Radians x -> Degrees xdefdegrees(x):'''Degrees derived from radians.'''return180*x/pi# unlines :: [String] -> Stringdefunlines(xs):'''A single newline-delimited string derived       from a list of strings.'''return'\n'.join(xs)# unwords :: [String] -> Stringdefunwords(xs):'''A space-separated string derived from       a list of words.'''return' '.join(xs)if__name__=='__main__':main()
Output:
Difference between two bearings:                  20 +                  45  ->     25.0                 -45 +                  45  ->     90.0                 -85 +                  90  ->    175.0                 -95 +                  90  ->   -175.0                 -45 +                 125  ->    170.0                 -45 +                 145  ->   -170.0  -70099.74233810938 +   29840.67437876723  ->  -139.58  -165313.6666297357 +    33693.9894517456  ->   -72.34  1174.8380510598456 + -154146.66490124757  ->   -161.5   60175.77306795546 +   42213.07192354373  ->     37.3

Hopefully a lot simpler, elegant and efficient by avoiding conditional statement and trigonometric functions

The table output use print formatting only available from python 3. Tested with 3.6.

Works with:Python version 3.6
"""Difference between two bearings"""defdelta_bearing(b1,b2):return((b2-b1+540)%360)-180dataSet=[[20,45],[-45,45],[-85,90],[-95,90],[-45,125],[-45,145], \[29.4803,-88.6381],[-78.3251,-159.036], \[-70099.74233810938,29840.67437876723], \[-165313.6666297357,33693.9894517456], \[1174.8380510598456,-154146.66490124757], \[60175.77306795546,42213.07192354373]]print('.{:-^19}.{:-^19}.{:-^9}.'.format(" b1 "," b2 "," Δ b "))forΔindataSet:print('|{: > 19}|{: > 19}|{: > 9.4f}|'.format(Δ[0],Δ[1],delta_bearing(Δ[0],Δ[1])))
Output:
.------- b1 --------.------- b2 --------.-- Δ b --.|                 20|                 45|  25.0000||                -45|                 45|  90.0000||                -85|                 90| 175.0000||                -95|                 90|-175.0000||                -45|                125| 170.0000||                -45|                145|-170.0000||            29.4803|           -88.6381|-118.1184||           -78.3251|           -159.036| -80.7109|| -70099.74233810938|  29840.67437876723|-139.5833|| -165313.6666297357|   33693.9894517456| -72.3439|| 1174.8380510598456|-154146.66490124757|-161.5030||  60175.77306795546|  42213.07192354373|  37.2989|

Quackery

Using the Quackery big number rational arithmetic librarybigrat.qky.

  [ $ "bigrat.qky" loadfile ] now!  [ v- -v    proper rot    360 mod    unrot improper    180 1 2over v< iff      [ 360 1 v- ] done    2dup -180 1 v< if      [ 360 1 v+ ] ]    is angledelta ( n/d n/d --> n/d )  ' [ [ $      "20"               $      "45"             ]      [ $     "-45"               $      "45"             ]      [ $      "85"               $      "90"             ]      [ $     "-95"               $      "90"             ]      [ $     "-45"               $     "125"             ]      [ $      "45"               $     "145"             ]      [ $      "29.4803"          $     "-88.6361"        ]      [ $     "-78.3251"          $    "-159.0360"        ]      [ $  "-70099.74233810938"   $   "29840.67437876723" ]      [ $ "-165313.6666297357"    $   "33693.9894517456"  ]      [ $    "1174.8380510598456" $ "-154146.66490124757" ]      [ $   "60175.773067955546"  $   "42213.07192354373" ] ]   witheach    [ do      dip [ $->v drop ]      $->v drop      angledelta      20 point$ echo$ cr ]
Output:
25905-175170100-118.1164-80.7109-139.58328312339-72.3439185187-161.502952307415637.298855588184

R

diff_bearing<-function(b1,b2){r<-(b2-b1)%%360ifelse(r>180,r-360,r)}test_bearings<-list(c(20,45),c(-45,45),c(-85,90),c(-95,90),c(-45,125),c(-45,145),c(29.4803,-88.6381),c(-78.3251,-159.036))test_bigbearings<-list(c(-70099.74233810938,29840.67437876723),c(-165313.6666297357,33693.9894517456),c(1174.8380510598456,-154146.66490124757),c(60175.77306795546,42213.07192354373))db_unary<-function(v)do.call(diff_bearing,as.list(v))sapply(test_bearings,db_unary)sapply(test_bigbearings,db_unary)
Output:
[1]   25.0000   90.0000  175.0000 -175.0000  170.0000 -170.0000 -118.1184  -80.7109[1] -139.58328  -72.34392 -161.50295   37.29886

Racket

see my comments in discussion regards bearing-heading or vice versa

#langracket(define(%ab)(-a(*b(truncate(/ab)))))(define(bearing-bearingheading)(-(%(+(%(-bearingheading)360)540)360)180))(module+main(bearing-2045)(bearing--4545)(bearing--8590)(bearing--9590)(bearing--45125)(bearing--45145)(bearing-29.4803-88.6381)(bearing--78.3251-159.036)(bearing--70099.7423381093829840.67437876723)(bearing--165313.666629735733693.9894517456)(bearing-1174.8380510598456-154146.66490124757)(bearing-60175.7730679554642213.07192354373))(module+test(requirerackunit)(check-equal?(%7.510)7.5)(check-equal?(%17.510)7.5)(check-equal?(%-7.510)-7.5)(check-equal?(%-17.510)-7.5))
Output:
-25-90-175175-170170118.1183999999999580.71090000000004139.5832831233856372.34391851868713161.50295230740448-37.29885558826936

Raku

(formerly Perl 6)

Works with:Rakudo version 2016.11
subinfix:<∠> (Real $b1, Real $b2) {   (my $b = ($b2 - $b1 + 720) % 360) > 180 ?? $b - 360 !! $b;}for 20, 45,   -45, 45,   -85, 90,   -95, 90,   -45, 125,   -45, 145,   29.4803, -88.6381,   -78.3251, -159.036,   -70099.74233810938, 29840.67437876723,   -165313.6666297357, 33693.9894517456,   1174.8380510598456, -154146.66490124757,   60175.77306795546, 42213.07192354373  ->$b1,$b2 {printf"%10.2f %10.2f = %8.2f\n",$b1,$b2,$b1$b2 }
Output:
     20.00      45.00 =    25.00    -45.00      45.00 =    90.00    -85.00      90.00 =   175.00    -95.00      90.00 =  -175.00    -45.00     125.00 =   170.00    -45.00     145.00 =  -170.00     29.48     -88.64 =  -118.12    -78.33    -159.04 =   -80.71 -70099.74   29840.67 =  -139.58-165313.67   33693.99 =   -72.34   1174.84 -154146.66 =  -161.50  60175.77   42213.07 =    37.30

Red

anglediff:func[b1b2/localr][r:mod(b2- b1)360eitherr>=180[r-360][r]]b1:180b2:-180test-list:[[2045][-4545][-8590][-9590][-45125][-45145][29.4803-88.6381][-78.3251-159.036]]foreachtest-casetest-list[b1:test-case/1b2:test-case/2print["b1 : "b1" b2 : "b2"angle diff b2 - b1 : "(anglediffb1 b2)]]

REXX

Some extra coding was added for a better visual presentation;   the angles were centered,   the answers were aligned.

/*REXX pgm calculates difference between two angles (in degrees), normalizes the result.*/numericdigits25/*use enough dec. digits for angles*/callshow20,45/*display angular difference (deg).*/callshow-45,45/*   "       "        "        "   */callshow-85,90/*   "       "        "        "   */callshow-95,90/*   "       "        "        "   */callshow-45,125/*   "       "        "        "   */callshow45,145/*   "       "        "        "   */callshow29.4803,-88.6361/*   "       "        "        "   */callshow-78.3251,-159.036/*   "       "        "        "   */callshow-70099.74233810938,29840.67437876723/*   "       "        "        "   */callshow-165313.6666297357,33693.9894517456/*   "       "        "        "   */callshow1174.8380510598456,-154146.66490124757/*   "       "        "        "   */callshow60175.773067955546,42213.07192354373/*   "       "        "        "   */exit/*stick a fork in it,  we're done. *//*──────────────────────────────────────────────────────────────────────────────────────*/show:parsearga,b;d=digits();$='º'/*obtain the 2 angles (are in degrees).*/x=format(((((b-a)//360)+540)//360)-180,4,d)/*compute and format.  */ifpos(.,x)\==0thenx=strip(strip(x,'T',0),"T",.)/*strip trailing chaff.*/saycenter(a||$,d)'─'center(b||$,d)" ────► "x||$return/* [↑]  display the angular difference.*/
output:
           20º            ─            45º             ────►    25º          -45º            ─            45º             ────►    90º          -85º            ─            90º             ────►   175º          -95º            ─            90º             ────►  -175º          -45º            ─           125º             ────►   170º           45º            ─           145º             ────►   100º        29.4803º          ─         -88.6361º          ────►  -118.1164º        -78.3251º         ─         -159.036º          ────►   -80.7109º   -70099.74233810938º    ─    29840.67437876723º      ────►  -139.58328312339º   -165313.6666297357º    ─     33693.9894517456º      ────►   -72.3439185187º   1174.8380510598456º    ─   -154146.66490124757º     ────►  -161.5029523074156º   60175.773067955546º    ─    42213.07192354373º      ────►    37.298855588184º

Ring

# Project : Angle difference between two bearingsdecimals(4)see "Input in -180 to +180 range:" + nlsee getDifference(20.0, 45.0) + nlsee getDifference(-45.0, 45.0) + nlsee getDifference(-85.0, 90.0) + nlsee getDifference(-95.0, 90.0) + nlsee getDifference(-45.0, 125.0) + nlsee getDifference(-45.0, 145.0) + nlsee getDifference(-45.0, 125.0) + nlsee getDifference(-45.0, 145.0) + nlsee getDifference(29.4803, -88.6381) + nlsee getDifference(-78.3251, -159.036) + nl func getDifference(b1, b2)     r = (b2 - b1) % 360.0     if r >= 180.0        r = r - 360.0     end     return r

Output:

Input in -180 to +180 range:2590175-175170-170170-170-118.1184-80.7109

RPL

≪ SWAP - 360 MODIF DUP 180 >THEN 360 -END ≫ 'BDIFF' STO
Input:
20 45 BDIFF-45 45  BDIFF-85 90  BDIFF-95 90  BDIFF-45 125  BDIFF-45 145  BDIFF29.4803 -88.6381  BDIFF-78.3251 -159.036  BDIFF
Output:
8:                  257:                  906                  1755:                -1754:                 1703:                -1702:           -118.11841:            -80.7109

Ruby

Translation of:C++
defgetDifference(b1,b2)r=(b2-b1)%360.0# Ruby modulus has same sign as divisor, which is positive here,# so no need to consider negative caseifr>=180.0r-=360.0endreturnrendif__FILE__==$PROGRAM_NAMEputs"Input in -180 to +180 range"putsgetDifference(20.0,45.0)putsgetDifference(-45.0,45.0)putsgetDifference(-85.0,90.0)putsgetDifference(-95.0,90.0)putsgetDifference(-45.0,125.0)putsgetDifference(-45.0,145.0)putsgetDifference(-45.0,125.0)putsgetDifference(-45.0,145.0)putsgetDifference(29.4803,-88.6381)putsgetDifference(-78.3251,-159.036)puts"Input in wider range"putsgetDifference(-70099.74233810938,29840.67437876723)putsgetDifference(-165313.6666297357,33693.9894517456)putsgetDifference(1174.8380510598456,-154146.66490124757)putsgetDifference(60175.77306795546,42213.07192354373)end
Output:
Input in -180 to +180 range25.090.0175.0-175.0170.0-170.0170.0-170.0-118.11840000000001-80.71089999999998Input in wider range-139.58328312338563-72.34391851868713-161.5029523074044837.29885558826936

Rust

/// Calculate difference between two bearings, in -180 to 180 degrees rangepubfnangle_difference(bearing1:f64,bearing2:f64)->f64{letdiff=(bearing2-bearing1)%360.0;ifdiff<-180.0{360.0+diff}elseifdiff>180.0{-360.0+diff}else{diff}}#[cfg(test)]modtests{usesuper::*;#[test]fntest_angle_difference(){assert_eq!(25.00,angle_difference(20.00,45.00));assert_eq!(90.00,angle_difference(-45.00,45.00));assert_eq!(175.00,angle_difference(-85.00,90.00));assert_eq!(-175.00,angle_difference(-95.00,90.00));assert_eq!(170.00,angle_difference(-45.00,125.00));assert_eq!(-170.00,angle_difference(-45.00,145.00));approx_eq(-118.1184,angle_difference(29.4803,-88.6381));approx_eq(-80.7109,angle_difference(-78.3251,-159.036));approx_eq(-139.5832,angle_difference(-70099.74233810938,29840.67437876723));approx_eq(-72.3439,angle_difference(-165313.6666297357,33693.9894517456));approx_eq(-161.5029,angle_difference(1174.8380510598456,-154146.66490124757));approx_eq(37.2988,angle_difference(60175.77306795546,42213.07192354373));}// approximate equality on floats.// see also https://crates.io/crates/float-cmpfnapprox_eq(f1:f64,f2:f64){assert!((f2-f1).abs()<0.0001,"{} != {}",f1,f2)}}

Scala

Output:

Best seen running in your browser either byScalaFiddle (ES aka JavaScript, non JVM) orScastie (remote JVM).

objectAngleDifferenceextendsApp{privatedefgetDifference(b1:Double,b2:Double)={valr=(b2-b1)%360.0if(r<-180.0)r+360.0elseif(r>=180.0)r-360.0elser}println("Input in -180 to +180 range")println(getDifference(20.0,45.0))println(getDifference(-45.0,45.0))println(getDifference(-85.0,90.0))println(getDifference(-95.0,90.0))println(getDifference(-45.0,125.0))println(getDifference(-45.0,145.0))println(getDifference(-45.0,125.0))println(getDifference(-45.0,145.0))println(getDifference(29.4803,-88.6381))println(getDifference(-78.3251,-159.036))println("Input in wider range")println(getDifference(-70099.74233810938,29840.67437876723))println(getDifference(-165313.6666297357,33693.9894517456))println(getDifference(1174.8380510598456,-154146.66490124757))println(getDifference(60175.77306795546,42213.07192354373))}

Scheme

R6RS standard.

#!r6rs(import(rnrsbase(6))(rnrsiosimple(6)))(define(bearing-differencebearing-2bearing-1)(-(mod(+(mod(-bearing-2bearing-1)360)540)360)180))(define(bearing-difference-test)(definetest-cases'((2045)(-4545)(-8590)(-9590)(-45125)(-45145)(29.4803-88.6381)(-78.3251-159.036)(-70099.7423381093829840.67437876723)(-165313.666629735733693.9894517456)(1174.8380510598456-154146.66490124757)(60175.7730679554642213.07192354373)))(for-each(lambda(argument-list)(display(applybearing-differenceargument-list))(newline))test-cases))
Output:
> (bearing-difference-test)-25-90-175175-170170118.1183999999999580.71090000000004139.5832831233856372.34391851868713161.50295230740448-37.29885558826936

Seed7

The libraryfloat.s7i supports theoperatormod,which can be used to solve this task easily.

$ include "seed7_05.s7i";  include "float.s7i";const func float: getDifference (in float: b1, in float: b2) is func  result    var float: difference is 0.0;  begin    difference := (b2 - b1) mod 360.0;    if difference > 180.0 then      difference -:= 360.0;    end if;  end func;const proc: main is func  begin    writeln("Input in -180 to +180 range");    writeln(getDifference(20.0, 45.0));    writeln(getDifference(-45.0, 45.0));    writeln(getDifference(-85.0, 90.0));    writeln(getDifference(-95.0, 90.0));    writeln(getDifference(-45.0, 125.0));    writeln(getDifference(-45.0, 145.0));    writeln(getDifference(-45.0, 125.0));    writeln(getDifference(-45.0, 145.0));    writeln(getDifference(29.4803, -88.6381));    writeln(getDifference(-78.3251, -159.036));    writeln("Input in wider range");    writeln(getDifference(-70099.74233810938, 29840.67437876723));    writeln(getDifference(-165313.6666297357, 33693.9894517456));    writeln(getDifference(1174.8380510598456, -154146.66490124757));    writeln(getDifference(60175.77306795546, 42213.07192354373));  end func;
Output:
Input in -180 to +180 range25.090.0175.0-175.0170.0-170.0170.0-170.0-118.1184-80.7109Input in wider range-139.583283123386-72.3439185186871-161.50295230740437.2988555882694

Sidef

funcbearingAngleDiff(b1,b2){(varb=((b2-b1+720)%360))>180?(b-360):b}printf("%25s %25s %25s\n","B1","B2","Difference")printf("%25s %25s %25s\n","-"*20,"-"*20,"-"*20)forb1,b2in([20,45-45,45-85,90-95,90-45,125-45,14529.4803,-88.6381-78.3251,-159.036-70099.74233810938,29840.67437876723-165313.6666297357,33693.98945174561174.8380510598456,-154146.6649012475760175.77306795546,42213.07192354373].slices(2)){printf("%25s %25s %25s\n",b1,b2,bearingAngleDiff(b1,b2))}
Output:
                       B1                        B2                Difference     --------------------      --------------------      --------------------                       20                        45                        25                      -45                        45                        90                      -85                        90                       175                      -95                        90                      -175                      -45                       125                       170                      -45                       145                      -170                  29.4803                  -88.6381                 -118.1184                 -78.3251                  -159.036                  -80.7109       -70099.74233810938         29840.67437876723          -139.58328312339       -165313.6666297357          33693.9894517456            -72.3439185187       1174.8380510598456       -154146.66490124757        -161.5029523074156        60175.77306795546         42213.07192354373            37.29885558827

Swift

funcangleDifference(a1:Double,a2:Double)->Double{letdiff=(a2-a1).truncatingRemainder(dividingBy:360)ifdiff<-180.0{return360.0+diff}elseifdiff>180.0{return-360.0+diff}else{returndiff}}lettestCases=[(20.0,45.0),(-45,45),(-85,90),(-95,90),(-45,125),(-45,145),(29.4803,-88.6381),(-78.3251,-159.036),(-70099.74233810938,29840.67437876723),(-165313.6666297357,33693.9894517456),(1174.8380510598456,-154146.66490124757),(60175.77306795546,42213.07192354373)]print(testCases.map(angleDifference))
Output:
[25.0, 90.0, 175.0, -175.0, 170.0, -170.0, -118.1184, -80.7109, -139.58328312338563, -72.34391851868713, -161.50295230740448, 37.29885558826936]

Tcl

procangleDiff{b1b2}{setangle[::tcl::mathfunc::fmod[expr($b2-$b1)]360]if{$angle<-180.0}{setangle[expr$angle+360.0]}if{$angle>=180.0}{setangle[expr$angle-360.0]}return$angle}puts"Input in -180 to +180 range"puts[angleDiff20.045.0]puts[angleDiff-45.045.0]puts[angleDiff-85.090.0]puts[angleDiff-95.090.0]puts[angleDiff-45.0125.0]puts[angleDiff-45.0145.0]puts[angleDiff-45.0125.0]puts[angleDiff-45.0145.0]puts[angleDiff29.4803-88.6381]puts[angleDiff-78.3251-159.036]puts"Input in wider range"puts[angleDiff-70099.7423381093829840.67437876723]puts[angleDiff-165313.666629735733693.9894517456]puts[angleDiff1174.8380510598456-154146.66490124757]puts[angleDiff60175.7730679554642213.07192354373]
Output:
Input in -180 to +180 range25.090.0175.0-175.0170.0-170.0170.0-170.0-118.1184-80.7109Input in wider range-139.58328312338563-72.34391851868713-161.5029523074044837.29885558826936

Uiua

Truncated inputs to 4 d.p. and outputs to 3 d.p. as we're not flying cruise missiles here.

Wrap ← ◌◌⍢(⊙⟜+|<⊙⋅∘)⊙◌⊢⟜(⍢(⊙⟜-|>⊙⋅∘)⊣)⟜/-Diff ← Wrap [¯180 180]/-[20_45 ¯45_45 ¯85_90 ¯95_90 ¯45_125 ¯45_145 29.4803_¯88.6381 ¯78.3251_¯159.036]≡(⁅₃Diff)[¯70099.7423_29840.6744 ¯165313.6666_33693.9895 1174.8381_¯154146.6649 60175.7731_42213.0719]≡(⁅₃Diff)
Output:
[25 90 175 ¯175 170 ¯170 ¯118.118 ¯80.711][¯139.583 ¯72.344 ¯161.503 37.299]

V (Vlang)

Translation of:go
import mathtype Bearing = f64 const test_cases = [    [Bearing(20), 45],    [Bearing(-45), 45],    [Bearing(-85), 90],    [Bearing(-95), 90],    [Bearing(-45), 125],    [Bearing(-45), 145],    [Bearing(29.4803), -88.6381],    [Bearing(-78.3251), -159.036],] fn main() {    for tc in test_cases {        println(tc[1].sub(tc[0]))        println(angle_difference(tc[1],tc[0]))    }} fn (b2 Bearing) sub(b1 Bearing) Bearing {    d := b2 - b1    match true {        d < -180 {            return d + 360        }        d > 180 {            return d - 360        }        else {            return d        }    }}fn angle_difference(b2 Bearing, b1 Bearing) Bearing {    return math.mod(math.mod(b2-b1, 360)+360+180, 360) - 180}
Output:
25.25.9090175.175.-175.-175.170170-170-170-118.1184-118.11840000000001-80.7109-80.71089999999998

Wren

varsubtract=Fn.new{|b1,b2|vard=(b2-b1)%360if(d<-180)d=d+360if(d>=180)d=d-360return(d*10000).round/10000// to 4dp}varpairs=[[20,45],[-45,45],[-85,90],[-95,90],[-45,125],[-45,145],[29.4803,-88.6381],[-78.3251,-159.036],[-70099.74233810938,29840.67437876723],[-165313.6666297357,33693.9894517456],[1174.8380510598456,-154146.66490124757],[60175.77306795546,42213.07192354373]]System.print("Differences (to 4dp) between these bearings:")for(pairinpairs){varp0=pair[0]varp1=pair[1]vardiff=subtract.call(p0,p1)varoffset=(p0<0)?" ":"  "System.print("%(offset)%(p0) and%(p1) ->%(diff)")}
Output:
Differences (to 4dp) between these bearings:  20 and 45 -> 25 -45 and 45 -> 90 -85 and 90 -> 175 -95 and 90 -> -175 -45 and 125 -> 170 -45 and 145 -> -170  29.4803 and -88.6381 -> -118.1184 -78.3251 and -159.036 -> -80.7109 -70099.742338109 and 29840.674378767 -> -139.5833 -165313.66662974 and 33693.989451746 -> -72.3439  1174.8380510598 and -154146.66490125 -> -161.503  60175.773067955 and 42213.071923544 -> 37.2989

XBS

settype Bearing = {Angle:number}class Bearing {    private method construct(Angle:number=0)    self.Angle=(((Angle%360)+540)%360)-180;    method ToString():string    send tostring(math.nround(self.Angle,4))+"°";    private method __sub(b2:Bearing):Bearing{    send new Bearing(self.Angle-b2.Angle);    }} const BearingAngles:[[number]] = [    [20,45],    [-45,45],    [-85,90],    [-95,90],    [-45,125],    [-45,145],    [29.4803,-88.6381],    [-78.3251,-159.036],    [-70099.74233810938,29840.67437876723],    [-165313.6666297357,33693.9894517456],    [1174.8380510598456,-154146.66490124757],    [60175.77306795546,42213.07192354373]]; foreach(v of BearingAngles){    set b1:Bearing=new Bearing(v[0]);    set b2:Bearing=new Bearing(v[1]);    log(b2::ToString()+" - "+b1::ToString()+" = "+(b2-b1)::ToString());}
Output:
45° - 20° = 25°45° - -45° = 90°90° - -85° = 175°90° - -95° = -175°125° - -45° = 170°145° - -45° = -170°-88.6381° - 29.4803° = -118.1184°-159.036° - -78.3251° = -80.7109°-39.3256° - 100.2577° = -139.5833°-146.0105° - -73.6666° = -72.3439°-66.6649° - 94.8381° = -161.503°93.0719° - 55.7731° = 37.2989°

XPL0

Pairs of bearing angles are input from the console or from a file(terminated with Ctrl+C) redirected on the command line.

real    B1, B2, Ang;[Text(0, "   Bearing 1       Bearing 2      Difference");loop   [B1:= RlIn(1);        B2:= RlIn(1);        Ang:= B2 - B1;        while Ang >  180. do Ang:= Ang - 360.;        while Ang < -180. do Ang:= Ang + 360.;        CrLf(0);        RlOut(0, B1);  ChOut(0, 9);        RlOut(0, B2);  ChOut(0, 9);        RlOut(0, Ang);       ];]
Output:
   Bearing 1       Bearing 2      Difference   20.00000        45.00000        25.00000  -45.00000        45.00000        90.00000  -85.00000        90.00000       175.00000  -95.00000        90.00000      -175.00000  -45.00000       125.00000       170.00000  -45.00000       145.00000      -170.00000   29.48030       -88.63810      -118.11840  -78.32510      -159.03600       -80.71090-70099.74234    29840.67438      -139.58328-165313.66663   33693.98945       -72.34392 1174.83805     -154146.66490    -161.5029560175.77307     42213.07192        37.29886

zkl

Translation of:Raku
fcn bearingAngleDiff(b1,b2){  // -->Float, b1,b2 can be int or float  ( (b:=(0.0 + b2 - b1 + 720)%360) > 180 ) and b - 360 or b;}
T( 20,45, -45,45, -85,90, -95,90, -45,125, -45,145 ).pump(Console.println,Void.Read,      fcn(b1,b2){ "%.1f\UB0; + %.1f\UB0; = %.1f\UB0;"                  .fmt(b1,b2,bearingAngleDiff(b1,b2)) });
Output:
20.0° + 45.0° = 25.0°-45.0° + 45.0° = 90.0°-85.0° + 90.0° = 175.0°-95.0° + 90.0° = -175.0°-45.0° + 125.0° = 170.0°-45.0° + 145.0° = -170.0°

References

  1. [1]
Retrieved from "https://rosettacode.org/wiki/Angle_difference_between_two_bearings?oldid=391894"
Categories:
Hidden category:
Cookies help us deliver our services. By using our services, you agree to our use of cookies.

[8]ページ先頭

©2009-2026 Movatter.jp