Q:

A programming language that allows you to define new limits for simple types

Many languages like C++, C#, and Java allow you to create objects that represent simple types like integer or float. Using a class interface you can override operators and perform logic like checking if a value exceeds a business rule of 100.
I'm wondering if it's possible in some languages to define these rules as annotations or attributes of a variable/property.
For example, in C# you might write:
[Range(0,100)]
public int Price { get; set; }

Or maybe in C++ you could write:
int(0,100) x = 0;

I've never seen something like this done, but given how dependent we have become on data validation before storage. It's strange that this feature hasn't been added to languages.
Can you give example of languages where this is possible? 

A:

Pascal had subrange types, i.e. decreasing the number of numbers that fit into a variable.
  TYPE name = val_min .. val_max;

Ada also has a notion of ranges: http://en.wikibooks.org/wiki/Ada_Programming/Types/range
From Wikipedia.... 
type Day_type   is range    1 ..   31;
type Month_type is range    1 ..   12;
type Year_type  is range 1800 .. 2100;
type Hours is mod 24;
type Weekday is (Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday); 

can also do 
subtype Weekend is  Weekday (Saturday..Sunday);
subtype WorkDay is  Weekday (Monday..Friday);

And here's where it gets cool 
year : Year_type := Year_type`First -- 1800 in this case...... 

C does not have a strict subrange type, but there are ways to mimic one (at least limited) by using bitfields to minimize the number of bits used. struct {int a : 10;} my_subrange_var;}. This can work as an upper bound for variable content (in general I would say: don't use bitfields for this, this is just to proof a point).
A lot of solutions for arbitrary-length integer types in other languages rather happen on the library-level, I.e. C++ allows for template based solutions.
There are languages that allow for monitoring of variable states and connecting assertions to it. For example in Clojurescript
(defn mytest 
   [new-val] 
   (and (< new-val 10)
        (<= 0 new-val)))

(def A (atom 0 :validator mytest))

The function mytest is called when a has changed (via reset! or swap!) checks whether conditions are met. This could be an example for implementing subrange behaviour in late-binding languages (see http://blog.fogus.me/2011/09/23/clojurescript-watchers-and-validators/ ).

A:

Ada also is a language that allows limits for simple types, in fact in Ada it's good practice to define your own types for your program to guarantee correctness.
type MyType1   is range    1 .. 100;
type MyType2   is range    5 .. 15;

myVar1 : MyType1;

It was used for a long time by the DoD, maybe still is but I've lost track of it's current use.

A:

Some restricted form of your intention is to my knowledge possible in Java and C# through a combination of Annotations and Dynamic Proxy Pattern (there exist built-in implementations for dynamic proxies in Java and C#).
Java version
The annotation:
@Target(ElementType.PARAMETER)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface IntRange {
     int min ();
     int max ();
}

The Wrapper class creating the Proxy instance:
public class Wrapper {
    public static Object wrap(Object obj) {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new MyInvocationHandler(obj));
    }
}

The InvocationHandler serving as bypass at every method call:
public class MyInvocationHandler implements InvocationHandler {
    private Object impl;

    public MyInvocationHandler(Object obj) {
        this.impl = obj;
    }

@Override
public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable {
    Annotation[][] parAnnotations = method.getParameterAnnotations();
    Annotation[] par = null;
    for (int i = 0; i<parAnnotations.length; i++) {
        par = parAnnotations[i];
        if (par.length > 0) {
            for (Annotation anno : par) {
                if (anno.annotationType() == IntRange.class) {
                    IntRange range = ((IntRange) anno);
                    if ((int)args[i] < range.min() || (int)args[i] > range.max()) {
                        throw new Throwable("int-Parameter "+(i+1)+" in method \""+method.getName()+"\" must be in Range ("+range.min()+","+range.max()+")"); 
                    }
                }
            }
        }
    }
    return method.invoke(impl, args);
}
}

The Example-Interface for Usage:
public interface Example {
    public void print(@IntRange(min=0,max=100) int num);
}

Main-Method:
Example e = new Example() {
    @Override
    public void print(int num) {
        System.out.println(num);
    }
};
e = (Example)Wrapper.wrap(e);
e.print(-1);
e.print(10);

Output:
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy0.print(Unknown Source)
at application.Main.main(Main.java:13)
Caused by: java.lang.Throwable: int-Parameter 1 in method "print" must be in Range (0,100)
at application.MyInvocationHandler.invoke(MyInvocationHandler.java:27)
... 2 more

C#-Version
The annotation (in C# called attribute):
[AttributeUsage(AttributeTargets.Parameter)]
public class IntRange : Attribute
{
    public IntRange(int min, int max)
    {
        Min = min;
        Max = max;
    }

    public virtual int Min { get; private set; }

    public virtual int Max { get; private set; }
}

The DynamicObject Sub-Class:
public class DynamicProxy : DynamicObject
{
    readonly object _target;

    public DynamicProxy(object target)
    {
        _target = target;
    }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        TypeInfo clazz = (TypeInfo) _target.GetType();
        MethodInfo method = clazz.GetDeclaredMethod(binder.Name);
        ParameterInfo[] paramInfo = method.GetParameters();
        for (int i = 0; i < paramInfo.Count(); i++)
        {
            IEnumerable<Attribute> attributes = paramInfo[i].GetCustomAttributes();
            foreach (Attribute attr in attributes)
            {
                if (attr is IntRange)
                {
                    IntRange range = attr as IntRange;
                    if ((int) args[i] < range.Min || (int) args[i] > range.Max)
                        throw new AccessViolationException("int-Parameter " + (i+1) + " in method \"" + method.Name + "\" must be in Range (" + range.Min + "," + range.Max + ")");
                }
            }
        }

        result = _target.GetType().InvokeMember(binder.Name, BindingFlags.InvokeMethod, null, _target, args);

        return true;
    }
}

The ExampleClass:
public class ExampleClass
{
    public void PrintNum([IntRange(0,100)] int num)
    {
        Console.WriteLine(num.ToString());
    }
}

Usage:
    static void Main(string[] args)
    {
        dynamic myObj = new DynamicProxy(new ExampleClass());
        myObj.PrintNum(99);
        myObj.PrintNum(-5);
    }

In conclusion, you see that you can get something like that to work in Java, but it's not entirely convenient, because

Proxy class can just be instantiated for interfaces, i.e. your class has to implement an interface
Allowed Range can only be declared on interface level  
Later usage comes just with extra effort in the beginning (MyInvocationHandler, wrapping at every instantiation) which also slightly reduces understandability

The capabilities of DynamicObject class in C# remove the interface restriction, as you see in the C# implementation. Unfortunately, this dynamic behavior removes static type safety in in this case, so runtime checks are necessary to determine if a method call on the dynamic proxy is allowed.
If those restrictions are acceptable for you, then this can serve as a basis for further digging!

