I think the original thread was Degrees C to Degrees F. I needed to go the other way around, and I needed double precision numbers. I'm programming an oven controller that will run from 250F to 500 F (120C to 260 C). Someone else posted a nice, simple algorithm that would only handle numbers up to 128 C - too small. This algorithm checked OK with 32F, 212F, and 512 F with about 0.1% or 1 digit error at the upper end. It will not work correctly below 32F or above 65,534F (pretty &*^^%&*^% hot). here goes: I'm afraid my email package converts tabs to single spaces - you'll need to clean this up a bit. ;********************************************************************* **** ; ; MACROS ;********************************************************************* **** ; ;******************************************************************* ; Double Precision Addition ( ACCb + ACCa -> ACCb ) ; ; PRESER VES ACCA DOUBLEADD MACRO ACCALO, ACCAHI, ACCBLO, ACCBHI movf ACCaLO,W addwf ACCbLO, F ;add lsb btfsc STATUS,CARRY ;add in carry incf ACCbHI, F movf ACCaHI,W addwf ACCbHI, F ;add msb ENDM ;******************************************************** ;******************************************************************* ; Double Precision Subtraction ( ACCb - ACCa -> ACCb ) ; ; TRASHES ACCA DOUBLESUB MACRO ACCALO, ACCAHI, ACCBLO, ACCBHI ; FIRST NEGATE ACCALO: comf ACCaLO, F ; negate ACCa ( -ACCa -> ACCa ) incf ACCaLO, F btfsc STATUS,Z_bit decf ACCaHI, F comf ACCaHI, F ; THEN ADD: DOUBLEADD ACCALO,ACCAHI, ACCBLO, ACCBHI ENDM ; ; ;******************************************************************* ;********************************************************************* **** ; ; SUBROUTINES ;********************************************************************* **** ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; F_2_C ; DOUBLE BYTE DEGREES F TO DEGREES C CONVERTER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; F_2_C ; SUBROUTINE ;DEG_F IS A NUMBER BETWEEN 32 AND 65,535 STORED IN ; DEG_F AND DEG_FHI ;DEG_C IS A NUMBER BETWEEN 0 AND 36,390 STORED IN ; DEG_C AND DEG_CHI ; WILL NOT WORK FOR DEG_F < 32 OR DEG_C < 0 !! ; ALGORITM: DEG_C = DEG_F/2 + 1/16*DEG_F- 1/128*DEG_F+ 18 ; = .55469F+19 ; ABOUT 0.1% ACCURATE OVER 0 TO 512 F RANGE ; (DESIGNED TO BE GOOD FOR AN OVEN CONTROLLER) ; 212 F = 100 C PERFECT ; 32 F = 0C PERFECT ; 512 F = 266C REALLY 266.7C 0.1% OFF ; REMEMBER TO DECLARE THESE VARIABLES: ;CBLOCK
; TEMP ; TEMPHI ; DEG_F ; DEG_FHI ; DEG_C ; DEG_CHI ; ENDC BCF STATUS, CARRY ; CLEAR CARRY MOVF DEG_F, W ; RECALL DEG_F MOVWF TEMP ; REMEMBER DEG_F MOVF DEG_FHI, W ; RECALL DEG_FHI MOVWF TEMPHI ; REMEMBER IT BCF STATUS, CARRY ; CLEAR CARRY RRF TEMPHI, W ; TEMPHI/2 =>CARRY MOVWF TEMPHI MOVWF DEG_CHI RRF TEMP, W ; CARRY => TEMP/2 MOVWF TEMP MOVWF DEG_C ; DEG_C NOW = DEG_F/2 BCF STATUS, CARRY ; CLEAR CARRY RRF TEMPHI, F ; TEMPHI/4 => CARRY RRF TEMP, F ; TEMP/4 BCF STATUS, CARRY ; CLEAR CARRY RRF TEMPHI, F ; TEMPHI/8 => CARRY RRF TEMP, F ; TEMP/8 BCF STATUS, CARRY ; CLEAR CARRY RRF TEMPHI, F ; TEMPHI/16 => CARRY RRF TEMP, F ; TEMP/16 DOUBLEADD TEMP, TEMPHI, DEG_C, DEG_CHI BCF STATUS, CARRY ; CLEAR CARRY RRF TEMPHI, F ; TEMPHI/32 => CARRY RRF TEMP, F ; TEMP/32 BCF STATUS, CARRY ; CLEAR CARRY RRF TEMPHI, F ; TEMPHI/64 => CARRY RRF TEMP, F ; TEMP/64 BCF STATUS, CARRY ; CLEAR CARRY RRF TEMPHI, F ; TEMPHI/128 => CARRY RRF TEMP, F ; TEMP/128 DOUBLESUB TEMP, TEMPHI, DEG_C, DEG_CHI ; REMEMBER DOUBLESUB TRASHES TEMP CLRF TEMPHI MOVLW .18 MOVWF TEMP DOUBLESUB TEMP, TEMPHI, DEG_C, DEG_CHI ; DEG_C NOW CONTAINS CONVERTED NUMBER RETLW 0 ;********************************************************************* ******** ; MAIN ROUTINE ; ;********************************************************************* ******** MAIN MOVLW .1 MOVWF DEG_F CLRF DEG_FHI MAINLOOP CALL F_2_C NOP ; DOUBLE PRECISION INCREMENT DEG_F INCF DEG_F, F BTFSC STATUS, Z INCF DEG_FHI, F GOTO MAINLOOP END Best Regards, Lawrence Lile