Decimal number to fraction LISP

Decimal number to fraction LISP

jesusrperezd
Enthusiast Enthusiast
568 Views
5 Replies
Message 1 of 6

Decimal number to fraction LISP

jesusrperezd
Enthusiast
Enthusiast

Hi all,

 

I have a drawing that has some TEXTS and MTEXT with decimal numbers. I need to convert them to fractional numbers. The decimal part needs to be converted and rounded until the 16th denominator, that is, 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, 1/16, 3/16, 5/16, 7/16, 9/16, 11/16, 13/16, 15/16.

 

Let´s say we have "20.25", it will be "20-1/4"   ;    "1.49" will be "1-1/2"

 

I need to maintain the text style, color, font, rotation, height, alignment, etc.  There are a lot of values to be changed, so I´m looking for a way to do this quickly. I think launching the app and then touching every item once.

 

I really would appreciate your help finding a solution.

 

I got this code from AI, but it is not working, 

 

(defun round (num)
(if (< (rem num 1.0) 0.5)
(fix num)
(1+ (fix num))
)
)

(defun c:DecToFrac ( / en ed txt num int frac inc)
(setq en (car (entsel "\nSelect MText with decimal: ")))
(if (and en (setq ed (entget en)))
(progn
(setq txt (cdr (assoc 1 ed)))
(setq num (atof txt))
(setq int (fix num))
(setq frac (rem num 1.0))
(setq inc (round (* frac 16))) ; Assuming 16ths of an inch for fractions
(setq frac-text
(cond
((= inc 0) "")
((= inc 16) (progn (setq int (1+ int)) ""))
((= inc 8) "1/2")
((= inc 4) "1/4")
((= inc 12) "3/4")
((= inc 2) "1/8")
((= inc 6) "3/8")
((= inc 10) "5/8")
((= inc 14) "7/8")
((= inc 1) "1/16")
((= inc 3) "3/16")
((= inc 5) "5/16")
((= inc 7) "7/16")
((= inc 9) "9/16")
((= inc 11) "11/16")
((= inc 13) "13/16")
((= inc 15) "15/16")
)
)
(setq new-txt (strcat (itoa int) (if frac-text (strcat "-" frac-text) "")))
(entmod (subst (cons 1 new-txt) (assoc 1 ed) ed))
)
)
(princ)
)

0 Likes
Accepted solutions (1)
569 Views
5 Replies
Replies (5)
Message 2 of 6

LDShaw
Collaborator
Collaborator

Try this.

;;; ==============================================================================
;;; Lisp Name: dec_to_frac.lsp
;;; Author: Lonnie
;;; Date Created: 2025-01-07
;;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/decimal-number-to-fraction-lisp/td-p/13242382
;;; Last Edited: 
;;;
;;; DESCRIPTION:
;;; A routine to convert a decimal number in MText to a fractional representation 
;;; (e.g., 1/16 increments) for improved clarity in architectural and engineering drawings.
;;;
;;; Usage:
;;; 1. Load the Lisp routine.
;;; 2. Run the command "DecToFrac" in AutoCAD.
;;;
;;; Parameters:
;;; en ed txt num int frac inc frac-text new-txt
;;;
;;; Returns:
;;; None
;;;
;;; Notes:
;;; - Converts decimal text values (e.g., 1.25) into fractional formats (e.g., 1-1/4).
;;; - Supports rounding to the nearest sixteenth (1/16) by default.
;;; 
;;; Edits on 2024-08-16:
;;; - Refactored fraction mapping logic using an association list.
;;; - Improved rounding function for better accuracy.
;;; - Enhanced code readability and maintainability.
;;;
;;; ---------------------------- Main program --------------------------------

(defun RoundNearest (num base / rounded)
  ;; Rounds a number to the nearest fraction base (e.g., 1/16)
  (setq rounded (fix (+ num (/ base 2))))
  (* rounded base)
)

(defun FractionToText (frac / fraction-mapping)
  ;; Converts a fractional value (0-16) to a fractional text representation
  (setq fraction-mapping
    '(
      (0 . "")   (1 . "1/16") (2 . "1/8")  (3 . "3/16")
      (4 . "1/4") (5 . "5/16") (6 . "3/8")  (7 . "7/16")
      (8 . "1/2") (9 . "9/16") (10 . "5/8") (11 . "11/16")
      (12 . "3/4") (13 . "13/16") (14 . "7/8") (15 . "15/16")
      (16 . "")
    )
  )
  (cdr (assoc frac fraction-mapping))
)

(defun c:DecToFrac ( / en ed txt num int frac inc frac-text new-txt)
  ;; Converts decimal value in MText to fractional representation
  (if (and (setq en (car (entsel "\nSelect MText with decimal: ")))
           (setq ed (entget en))
           (setq txt (cdr (assoc 1 ed)))
           (setq num (atof txt)))
    (progn
      (setq int (fix num))
      (setq frac (rem num 1.0))
      (setq inc (RoundNearest (* frac 16) 1)) ; Rounds to nearest 1/16
      (if (= inc 16) 
        (progn (setq int (1+ int)) (setq inc 0))
      )
      (setq frac-text (FractionToText inc))
      (setq new-txt (strcat (itoa int) (if (not (equal frac-text "")) (strcat "-" frac-text) "")))
      (entmod (subst (cons 1 new-txt) (assoc 1 ed) ed))
    )
  )
  (princ)
)

Worked for me. 

0 Likes
Message 3 of 6

Kent1Cooper
Consultant
Consultant
Accepted solution

This can be a lot simpler.  The (rtos) function will do the fractional format and the rounding for you, given the appropriate arguments.  It just puts a space between the number and the fraction, rather than your preferred hyphen, but if that's the only space, it's easily replaced with a hyphen.  For example:

(vl-string-subst "-" " " (rtos (atof "20.25") 5 4))

returns

"20-1/4"

The 5 is for fractional mode, the 4 [when in Architectural or Fractional mode] is to round to the nearest 1/16.

The same given "20.3" returns

"20-5/16"

Given "1.49", it returns

"1-1/2"

So [minimally tested]:

 

(defun c:DecToFrac (/ esel ent edata)
  (while
    (and
      (setq esel (entsel "\nSelect Text/Mtext with decimal: "))
      (setq ent (car esel))
      (wcmatch (cdr (assoc 0 (setq edata (entget ent)))) "*TEXT")
    ); and
    (setq str (vl-string-subst "-" " " (rtos (atof (cdr (assoc 1 edata))) 5 4)))
    (entmod (subst (cons 1 str) (assoc 1 edata) edata))
  ); while
  (prin1)
)

 

Pick as many to convert as you want, in one running of the command.

It would not do well with Mtext that has internal formatting, or with content that is more than just the decimal numerical part.  It could be made to verify certain things beyond just whether you picked a Text or Mtext object, before proceeding, if desired.

 

[P.S.  The posting of the same question more than once is requiring unnecessary effort from some.]

Kent Cooper, AIA
Message 4 of 6

jesusrperezd
Enthusiast
Enthusiast

Thanks for this. It is not working with the Mtext, can you check the attached drawing? Im trying to convert the vertical mtext 14.95 or 16.50, etc but I got 0.

0 Likes
Message 5 of 6

jesusrperezd
Enthusiast
Enthusiast
Thanks for this. It maybe something wrong on my side. Below Kent1cooper sent a code, and I got the same issue with the texts; please check my response and the file I have attached to that message.
0 Likes
Message 6 of 6

Kent1Cooper
Consultant
Consultant

That's because it has formatting content, not just numerical content, as shown in the Properties palette:

Kent1Cooper_0-1736366931528.png

For me, after clearing the formatting, or Exploding it to plain Text, it works.

Kent Cooper, AIA
0 Likes