Is There a Neat Way to Represent a Fraction as an Attributed String

Is there a neat way to represent a fraction as an attributed string?

If you want to have arbitrary fractions represented correctly, you should set the UIFontFeatureTypeIdentifierKey and UIFontFeatureSelectorIdentifierKey to kFractionsType and kDiagonalFractionsSelector respectively for UIFontDescriptorFeatureSettingsAttribute in a custom UIFontDescriptor. For example you can say something like:

let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: 1000.0, height: 100.0))
let pointSize : CGFloat = 60.0
let systemFontDesc = UIFont.systemFontOfSize(pointSize,
weight: UIFontWeightLight).fontDescriptor()
let fractionFontDesc = systemFontDesc.fontDescriptorByAddingAttributes(
[
UIFontDescriptorFeatureSettingsAttribute: [
[
UIFontFeatureTypeIdentifierKey: kFractionsType,
UIFontFeatureSelectorIdentifierKey: kDiagonalFractionsSelector,
], ]
] )
label.font = UIFont(descriptor: fractionFontDesc, size:pointSize)
label.text = "The Fraction is: 23/271"

with the following result:

Sample Image

You can find more information here

Swift 3.0

extension UIFont
{
static func fractionFont(ofSize pointSize: CGFloat) -> UIFont
{
let systemFontDesc = UIFont.systemFont(ofSize: pointSize).fontDescriptor
let fractionFontDesc = systemFontDesc.addingAttributes(
[
UIFontDescriptorFeatureSettingsAttribute: [
[
UIFontFeatureTypeIdentifierKey: kFractionsType,
UIFontFeatureSelectorIdentifierKey: kDiagonalFractionsSelector,
], ]
] )
return UIFont(descriptor: fractionFontDesc, size:pointSize)
}
}

let label = UILabel()
label.backgroundColor = .white
let pointSize: CGFloat = 45.0
let string = "This is a mixed fraction 312/13"
let attribString = NSMutableAttributedString(string: string, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: pointSize), NSForegroundColorAttributeName: UIColor.black])
attribString.addAttributes([NSFontAttributeName: UIFont.fractionFont(ofSize: pointSize)], range: (string as NSString).range(of: "12/13"))
label.attributedText = attribString
label.sizeToFit()

Sample Image

How to display fraction text number over another?

This is just Apple sample code from the Introducing the New System Fonts video from WWDC 2015 put into a playground and using a UILabel to render plain text fractions using font features. [Updated for Swift 4]

//: Playground - noun: a place where people can play

import UIKit
import CoreGraphics

let pointSize : CGFloat = 60.0
let systemFontDesc = UIFont.systemFont(ofSize: pointSize,
weight: UIFont.Weight.light).fontDescriptor
let fractionFontDesc = systemFontDesc.addingAttributes(
[
UIFontDescriptor.AttributeName.featureSettings: [
[
UIFontDescriptor.FeatureKey.featureIdentifier: kFractionsType,
UIFontDescriptor.FeatureKey.typeIdentifier: kDiagonalFractionsSelector,
],
]
] )

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 100))

label.font = UIFont(descriptor: fractionFontDesc, size:pointSize)
label.text = "12/48" // note just plain numbers and a regular slash

Just tap on the eye in the playground and you will see a beautiful fraction.

Introducing the New System Fonts (WWDC 2015 at 20:24)

Where to place miscellaneous widely used functions?

I'd extend UIFont with your fractionFont method:

extension UIFont {
class func fractionFont() -> UIFont {
/* Code here */
}
}

Display fraction number in UILabel

I have created the following two helper functions which will return the unicode string for a given number (0-9) in subscript or superscript format:

-(NSString *)superscript:(int)num {

NSDictionary *superscripts = @{@0: @"\u2070", @1: @"\u00B9", @2: @"\u00B2", @3: @"\u00B3", @4: @"\u2074", @5: @"\u2075", @6: @"\u2076", @7: @"\u2077", @8: @"\u2078", @9: @"\u2079"};
return superscripts[@(num)];
}

-(NSString *)subscript:(int)num {

NSDictionary *subscripts = @{@0: @"\u2080", @1: @"\u2081", @2: @"\u2082", @3: @"\u2083", @4: @"\u2084", @5: @"\u2085", @6: @"\u2086", @7: @"\u2087", @8: @"\u2088", @9: @"\u2089"};
return subscripts[@(num)];
}

Once you have these declared, you can easily call something like this:

NSLog(@"%@/%@", [self superscript:5], [self subscript:6]);

Which would output the following:

⁵/₆

And even a screenshot for ya from my normal UILabel:

From the simulator

EDIT

Here's a function that will work with any fraction, including 37/100, for example:

-(NSString *)fraction:(int)numerator denominator:(int)denominator {

NSMutableString *result = [NSMutableString string];

NSString *one = [NSString stringWithFormat:@"%i", numerator];
for (int i = 0; i < one.length; i++) {
[result appendString:[self superscript:[[one substringWithRange:NSMakeRange(i, 1)] intValue]]];
}
[result appendString:@"/"];

NSString *two = [NSString stringWithFormat:@"%i", denominator];
for (int i = 0; i < two.length; i++) {
[result appendString:[self subscript:[[two substringWithRange:NSMakeRange(i, 1)] intValue]]];
}
return result;
}

Calling the following:

NSLog(@"%@", [self fraction:37 denominator:100]);

Logs ³⁷/₁₀₀.

How to write fraction value using html?

Try the following:

1<sup>1</sup>⁄<sub>2</sub>

Performant algorithm to rationalize floats

There's a Stern–Brocot tree implementation shown here, but you'll have to profile to see which is better.

Addendum: I've had good results using org.jscience.mathematics.number.Rational in linear systems; org.apache.commons.math.fraction.BigFraction offers several constructors for double that may be useful. All throw suitable exceptions for undefined values.

Getting numerator and denominator of a fraction in R

A character representation of the fraction is stored in an attribute:

x <- fractions(0.175)
> strsplit(attr(x,"fracs"),"/")
[[1]]
[1] "7" "40"


Related Topics



Leave a reply



Submit