ประเภทคณิตศาสตร์ใน TypeScript

Jan 28 2023
บทนำ คำว่า 'ประเภทคณิตศาสตร์' ในภาษาโปรแกรมเช่น Javascript หรือ Typescript นั้นดูแปลก บางทีก็บ้าไปหน่อย Javascript มีประเภทตัวเลขที่อนุญาตให้ดำเนินการทางคณิตศาสตร์ เช่น การบวก การลบ การคูณ และการหาร
ภาพจาก brgfx บน Freepik

การแนะนำ

คำว่า 'ประเภทคณิตศาสตร์' ในภาษาโปรแกรมเช่น Javascript หรือ Typescript นั้นดูแปลก บางทีก็บ้าไปหน่อย Javascript มี ประเภท ตัวเลขที่อนุญาตให้ดำเนินการทางคณิตศาสตร์ เช่น การบวก การลบ การคูณ และการหาร มีสิ่งอำนวยความสะดวกที่บีบบังคับอย่างแน่นหนาในภาษาที่เกิดจากยุคแรกๆ ของเว็บที่ "ข้อผิดพลาดไม่ใช่ตัวเลือก" ดังนั้น ภาษาจึง 'ให้อภัย' เพียงพอที่จะอนุญาตให้ดำเนินการเช่น

console.log(1 - "1");

พิจารณาข้อความที่คล้ายกัน

console.log(1 + "1");

การบีบบังคับดังกล่าวทำให้การใช้สตริงในการดำเนินการทางคณิตศาสตร์แบบง่าย ๆ เป็นเรื่องที่เงอะงะ ถึงกระนั้น กี่ครั้งแล้วที่เราทำงานหรือดีบั๊กแอปพลิเคชันซึ่งเก็บค่าตัวเลขไว้ในตัวแปรประเภทสตริงหรือจัดให้เป็นสตริงจากคำขอบริการ

ประเภทตัวเลขอื่นๆ

ตัวเลขจาวาสคริปต์เป็นแบบลอยตัว 64 บิต สิ่งนี้ใช้ได้ (จนถึงจุดหนึ่ง) สำหรับการจัดการการแสดงจำนวนจริง บทความเกี่ยวกับการวิเคราะห์เชิงตัวเลขและการใช้งานในแอพพลิเคชั่นส่วนหน้าคงต้องรอกันต่อไปครับ :)

ภาษาไม่มีประเภทจำนวนเต็ม ถ้าเราต้องการดำเนินการกับจำนวนเต็มและบีบบังคับค่าให้เป็นจำนวนเต็มที่ใกล้ที่สุดโดยอัตโนมัติ แล้วจำนวนเต็มล่ะ? เศษส่วน? จำนวนเชิงซ้อน? ควอเทอร์เนียน?

จะเป็นอย่างไรหากเราต้องการกำหนดประเภทหนึ่งให้กับอีกประเภทหนึ่งและดำเนินการทางคณิตศาสตร์พื้นฐานกับประเภทต่างๆ

จะเป็นอย่างไรหากเราต้องการพิจารณาประเภทตามอำเภอใจเป็นตัวถูกดำเนินการในสมการโดยที่ประเภทหนึ่งระบุว่าไม่รู้จักในสมการ จะเกิดอะไรขึ้นถ้า 'ประเภทคณิตศาสตร์' เช่น เศษส่วน มีตัวเศษหรือตัวส่วนระบุเป็นปริมาณที่ไม่รู้จักในสมการ

ตัวอย่างการปฏิบัติ

ฉันต้องพิจารณาคำถามเหล่านี้ในแอปพลิเคชัน EdTech ย้อนกลับไปในสมัย ​​Flash และ Flex ของฉัน แอปพลิเคชั่นการเรียนรู้นี้เกี่ยวข้องกับการแก้สมการของแบบฟอร์ม

W op X = Y op Z

โดยที่ตัวแปรW, X, YและZอาจเป็นจำนวนจริง จำนวนเต็ม จำนวนเต็ม หรือเศษส่วน เศษส่วนสามารถผสมและแสดงในรูปแบบลดหรือไม่ลดก็ได้

การดำเนินการถูกจำกัดไว้ที่การบวก ลบ คูณ หารเท่านั้น

ตัวแปรใดๆ ในสมการข้างต้นอาจเป็นตัวแปรที่ไม่รู้จักก็ได้ อนุญาตให้ส่วนทั้งหมด ตัวเศษ หรือตัวส่วนของเศษส่วนเป็นปริมาณที่ไม่รู้จักได้

สมการถูกสร้างขึ้นแบบไดนามิกโดยใช้เทมเพลตเฉพาะเกรด ตัวแปรแต่ละตัวมีข้อจำกัดเกี่ยวกับค่าตัวเลขที่สามารถสร้างขึ้นสำหรับสมการได้ ข้อจำกัดเหล่านี้อนุญาตให้ใช้เทมเพลตเดียวกันในหลายระดับชั้น

ตัวอย่างเช่น พิจารณาเทมเพลต

ว + X = ?

โดยที่เครื่องหมายคำถามแสดงถึงปริมาณที่ไม่รู้จักในสมการ

ตัวแปรWและXอาจถูกจำกัดเป็นจำนวนเต็มในช่วงเวลา [0, 5] และค่าที่ไม่รู้จักอาจถูกจำกัดให้อยู่ในช่วงเวลาเดียวกัน สิ่งนี้ช่วยให้เด็กอนุบาลและนักเรียนระดับประถมศึกษาปีที่ 1 ใช้การนับนิ้วเป็นวิธีการแก้ปัญหาทางจิตชั่วคราว ตัวอย่างเช่น,

0 + 2 = ?

1 + 4 = ?

เป็นการสร้างสมการที่ถูกต้องจากเทมเพลตด้านบนและข้อจำกัดระดับอนุบาลหรือชั้นประถมศึกษาปีที่ 1 อย่างไรก็ตาม,

2 + 5 = ?

ไม่ถูกต้อง อย่างไรก็ตาม อาจใช้ได้กับระดับชั้นที่สูงขึ้น

แม่แบบที่ซับซ้อนมากขึ้นอาจเป็นรูปแบบ

ว * X = ย + ?

โดยที่W, XและYอาจถูกจำกัดให้สุ่มตัวอย่างจากชุดค่าจำนวนเต็มที่ให้มา

ปัญหาเกี่ยวกับเศษส่วนอาจแสดงร่วมกับตัวแปรประเภทอื่นๆ ดังแสดงในสมการต่อไปนี้

1 1/4 + ? = 2 1/4

ทั่วไปจากสมการที่พิสูจน์ได้ในอนาคตคือ

A1 op A2 op A3 … op ? = 0

ตัวแปรใด ๆ อาจถูกกำหนดให้เป็นตัวแปรที่ไม่รู้จักในสมการ ในกรณีของตัวแปรที่มีหลายส่วน เช่น เศษส่วนหรือจำนวนเชิงซ้อน จะกำหนดให้ส่วนใดเป็นไม่ทราบก็ได้ ดังนั้น,

1 1/? + 2 = 3 1/2

เป็นสมการที่เป็นไปได้ที่นักเรียนสามารถแก้ได้โดยการป้อนค่าตัวส่วนที่ไม่รู้จัก สมการทั้งหมดถูกสร้างขึ้นตามข้อจำกัดที่ให้ไว้สำหรับแต่ละตัวแปร เป็นที่พึงปรารถนาอย่างยิ่งสำหรับระบบที่จะรองรับจำนวนเชิงซ้อนในรีลีสในอนาคตโดยไม่ต้องเปลี่ยนสถาปัตยกรรมพื้นฐานหรือการสร้างสมการ/การแก้ปัญหา

ประเภทคณิตศาสตร์

ฉันชอบสถาปัตยกรรมที่แสดงปริมาณที่แตกต่างกันด้วยโมเดลหรืออินเทอร์เฟซทั่วไป การพิจารณานี้ทำให้เกิดเอนทิตีที่เรียกว่าประเภทคณิตศาสตร์ อย่างหลวมๆ

BasicMathType เป็นคอนเทนเนอร์สำหรับค่าเดียวและอาจมีองค์ประกอบจำนวนหนึ่งที่ใช้ในการคำนวณค่านั้น ตัวอย่างเช่น เศษส่วน 1 3/4 มีทั้งส่วน ตัวเศษ และส่วน ซึ่งแต่ละส่วนมีค่าของตัวเอง ค่าเศษส่วนแสดงด้วยจำนวนจริง 1.75

อิน เทอร์เฟซ BasicMathTypeแสดงอยู่ด้านล่าง

อินเทอร์เฟซนี้ให้สัญญาระหว่างBasicMathTypeกับผู้บริโภค

ประเภททางคณิตศาสตร์สามารถใช้เป็นตัวแปร (และแม้แต่ปริมาณที่ไม่รู้จัก) โดยพลการในสมการทั่วไปจากส่วนก่อนหน้า อาจมีการระบุค่าที่เป็นรูปธรรมเพื่อสร้างสมการที่นักเรียนต้องป้อนคำตอบในใบสมัคร สมการทั่วไปสามารถแก้ไขได้ในเชิงสัญลักษณ์ ค่าเฉพาะสำหรับตัวแปรทั้งหมดและปริมาณที่ไม่รู้จักอาจใช้เพื่อตรวจสอบคำตอบของนักเรียน

เศษส่วนแสดงถึงประเภททางคณิตศาสตร์เฉพาะที่มีความสามารถเพิ่มเติม

ตัวอย่าง

มูลค่าของระบบนี้มาจากความทั่วไปและความสม่ำเสมอในการแปลงประเภทอัตโนมัติ ในกรณีที่ปริมาณอินพุต เช่น สตริง " a " หรือNaN ของ Javascript ถูกกำหนดให้กับประเภททางคณิตศาสตร์ อินพุตที่ไม่ถูกต้องจะถูกบังคับให้เป็นค่าดีฟอลต์สำหรับประเภทเสมอ นี่คือระบบตัวเลขและอนุญาตให้เล่นเฉพาะตัวเลขเท่านั้น :)

ไม่มีสิ่งใดที่ได้รับ การเลื่อนระดับเป็นสตริง Javascript ไม่มีการแสดงผลลัพธ์เป็นJavascript null , undefinedหรือNaN คำตอบที่เป็นตัวเลขมีไว้สำหรับการดำเนินการทางคณิตศาสตร์ในประเภทคณิตศาสตร์เสมอ แม้ว่าคำตอบจะไม่ได้กำหนดไว้โดยเฉพาะก็ตาม

ประเภทคณิตศาสตร์ยังคำนึงถึงโดเมนและช่วงของประเภทด้วย อนุญาตให้ดำเนินการทางคณิตศาสตร์กับจำนวนเต็ม (แสดงโดย คลาส WholeModel ) จำนวนเต็มเป็นจำนวนเต็มที่มากกว่าหรือเท่ากับศูนย์

พิจารณาการดำเนินการทางคณิตศาสตร์อย่างง่าย 1–5

ผลลัพธ์คือลบ 4 ซึ่งไม่ใช่จำนวนเต็ม ระบบประเภทคณิตศาสตร์สำหรับจำนวนเต็มตระหนักดีว่าปัญหานี้เป็นปัญหา มีสองวิธีแก้ปัญหาที่เป็นไปได้ โปรดทราบว่าการดำเนินการทางคณิตศาสตร์ทั้งหมดในประเภทคณิตศาสตร์จะส่งกลับค่า BasicMathTypeเป็นอย่างน้อยซึ่งสามารถอัปคาสต์ได้

วิธีหนึ่งคือเพื่อให้แน่ใจว่าผลลัพธ์ของการดำเนินการทางคณิตศาสตร์ของจำนวนเต็มจะถูกส่งกลับเป็นแบบจำลองจำนวนเต็ม ในกรณีนี้ ผลลัพธ์จะถูกบังคับให้เป็นจำนวนเต็มที่ใกล้เคียงที่สุด ซึ่งเป็นศูนย์

ทางเลือกอื่น (ซึ่งใช้ในระบบประเภทคณิตศาสตร์ปัจจุบัน) คือการคำนวณผลลัพธ์ที่ถูกต้องและส่งคืนอินสแตนซ์ของคลาสIntegerModel IntegerModelเป็นsuperclass ของBasicMathType

มีปัญหาที่คล้ายกันกับการหารจำนวนเต็มสองจำนวน เช่น 3 และ 5 ผลลัพธ์ที่ได้คือจำนวนจริง ไม่ใช่จำนวนเต็ม ระบบประเภทคณิตศาสตร์จะคำนวณผลลัพธ์ที่ถูกต้องและส่งคืนอินสแตนซ์ของคลาสRealModel โปรดทราบว่า 'แบบจำลอง' ในระบบนี้เป็นการใช้งานที่เป็นรูปธรรมของ 'ประเภท' ที่เป็นนามธรรม

ภาพรวมและการบีบบังคับแสดงให้เห็นได้ดีที่สุดจากหลายๆ ตัวอย่าง

1 — ตั้งค่าเศษส่วนโดยใช้สตริง ตั้ง ค่าคุณสมบัติ ผสมเป็นค่าtrue โดย อัตโนมัติ

frac.value = " 1  7/ 8   ";
expect(frac.whole).toEqual(1);
expect(frac.numerator).toEqual(7);
expect(frac.denominator).toEqual(8);
expect(frac.mixed).toBe(true);

const frac: FractionModel = new FractionModel();
frac.setFraction(0, 1, 3);

const frac2: FractionModel = new FractionModel();
frac2.setFraction(0, 1, 6);

const result: FractionType = frac.add(frac2) as FractionType;
result.reduced             = true;

expect(result.numerator).toEqual(1);
expect(result.denominator).toEqual(2);

const frac: FractionModel = new FractionModel();
frac.setFraction(2, 3, 4);

const result: FractionType = frac.subtract(0.5) as FractionType;
result.reduced             = true;

expect(result.whole).toEqual(2);
expect(result.numerator).toEqual(1);
expect(result.denominator).toEqual(4);

const frac: FractionModel = new FractionModel();
frac.setFraction(2, 3, 4);

const result: FractionType = frac.multiply("1 1/2") as FractionType;

expect(result.whole).toEqual(4);
expect(result.numerator).toEqual(1);
expect(result.denominator).toEqual(8);

const frac: FractionModel = new FractionModel();
frac.setFraction(0, 1, 3);

const frac2: FractionModel = new FractionModel();

const result: FractionType = frac.divide(frac2) as FractionType;

expect(result.whole).toEqual(0);
expect(result.numerator).toEqual(0);
expect(result.denominator).toEqual(1);

const frac: FractionModel = new FractionModel();
frac.setFraction(2, 2, 5);

const result: FractionType = frac.divide("3/7") as FractionType;
result.reduced             = true;

expect(result.whole).toEqual(5);
expect(result.numerator).toEqual(3);
expect(result.denominator).toEqual(5);

const frac: FractionModel = new FractionModel();
frac.setFraction(0, 1, 3);

const frac2: FractionModel = new FractionModel();

frac.divideAndReplace(frac2);

expect(frac.whole).toEqual(0);
expect(frac.numerator).toEqual(1);
expect(frac.denominator).toEqual(3);

const real: RealModel = new RealModel();
const frac: FractionModel = new FractionModel();

frac.setFraction(1, 3, 4);

real.value = frac;

expect(real.value).toEqual(1.75);

const real: RealModel = new RealModel();

real.value = 1.25;

const result: RealModel = real.subtract("1.0") as RealModel;

expect(result.value).toEqual(0.25);

const real: RealModel = new RealModel();

real.value = 1.25;

const result: RealModel = real.multiply("2.0") as RealModel;

expect(result.value).toEqual(2.5);

const int: IntegerModel   = new IntegerModel();
const frac: FractionModel = new FractionModel();

frac.setFraction(1, 3,4);

int.value = frac;
expect(int.value).toEqual(2);

const int: IntegerModel  = new IntegerModel();

int.value = 1.25;

const result: IntegerModel = int.add("1") as IntegerModel;

expect(result.value).toEqual(2);

const int: IntegerModel  = new IntegerModel();

int.value = 1.25;

const result: IntegerModel = int.multiply(2) as IntegerModel;

expect(result.value).toEqual(2);

const whole: WholeModel   = new WholeModel();
const frac: FractionModel = new FractionModel();

frac.setFraction(1, 3,4);

whole.value = frac;
expect(whole.value).toEqual(2);

frac.setFraction(-1, 2,3);

whole.value = frac;
expect(whole.value).toEqual(0);

const whole: WholeModel  = new WholeModel();

whole.value = 1.25;

const result: BasicMathType    = whole.subtract(3);
const resultType: MathTypeEnum = result.type;

expect(resultType).toEqual(MathTypeEnum.INTEGER);
expect(result.value).toEqual(-2);

ตัวอย่างข้างต้นให้ข้อมูลคร่าวๆ เกี่ยวกับระบบประเภทคณิตศาสตร์ภายในไลบรารี AMYR ในขณะที่ EdTech เป็นพื้นที่แอปพลิเคชันที่ชัดเจนสำหรับความสามารถดังกล่าว ฉันใช้ระบบประเภทคณิตศาสตร์เวอร์ชัน Flash ActionScript ในแอปพลิเคชันทางธุรกิจหลายรายการ ตัวอย่างง่ายๆ อย่างหนึ่งที่ต้องการเปลี่ยนรูปแบบของผลลัพธ์ทางการเงินจากค่าทศนิยมแบบปัดเศษเป็นการแสดงเศษส่วนในส่วนต่างๆ ของแอปพลิเคชัน ค่าถูกป้อนลงในRealModelและแบบจำลองนั้นถูกกำหนดให้กับFractionModelตามต้องการ

ตามความสนใจ การสนับสนุนสำหรับคำจำกัดความของสมการ (ที่มีตัวแปรที่ไม่รู้จักตัวเดียวหรือส่วนที่ไม่รู้จักภายในตัวแปรที่ไม่รู้จัก) เป็นส่วนเพิ่มเติมที่เป็นไปได้มากที่สุด ซึ่งรวมถึงความสามารถในการแก้สมการและเปรียบเทียบคำตอบที่ป้อนกับคำตอบที่ถูกต้อง ประเภทคณิตศาสตร์ใหม่มักจะเป็นจำนวนเชิงซ้อนและควอเทอร์เนียน

ฉันหวังว่าคุณจะพบคุณค่าในอนาคตในระบบนี้ หรืออย่างน้อยก็สนุกไปกับการแยกโครงสร้างภายใน ลองใช้ห้องสมุด AMYR บน GitHub แล้วเริ่มต้นได้เลย!

เข้าร่วมกับเราที่ ng-conf 2023!

ng-conf | 14–15 มิถุนายน 2023
เวิร์กช็อป | 12–13 มิถุนายน 2566
สถานที่ | ซอลต์เลกซิตี ยูทาห์

ng-conf 2023เป็นการประชุมแบบแทร็กเดียวสองวันที่มุ่งเน้นการสร้างชุมชนเชิงมุม มาร่วมเป็นส่วนหนึ่งของกิจกรรมที่น่าทึ่งนี้ พบกับทีม Angular และชื่อที่ใหญ่ที่สุดในชุมชน เรียนรู้ล่าสุดใน Angular สร้างเครือข่ายของคุณ และพัฒนาทักษะของคุณ